diff options
author | Kaleb Keithley <kaleb@freedesktop.org> | 2003-11-14 15:54:30 +0000 |
---|---|---|
committer | Kaleb Keithley <kaleb@freedesktop.org> | 2003-11-14 15:54:30 +0000 |
commit | deae12c6b683898f5213992d561a59d4ea889cca (patch) | |
tree | 3ed14c7b76f47ec80c1868c34bd0e5de385db618 /src |
R6.6 is the Xorg base-lineXORG-MAIN
Diffstat (limited to 'src')
392 files changed, 86220 insertions, 0 deletions
diff --git a/src/AllCells.c b/src/AllCells.c new file mode 100644 index 00000000..495d9a36 --- /dev/null +++ b/src/AllCells.c @@ -0,0 +1,63 @@ +/* $Xorg: AllCells.c,v 1.4 2001/02/09 02:03:30 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#define NEED_REPLIES + +#include "Xlibint.h" + +Status XAllocColorCells(dpy, cmap, contig, masks, nplanes, pixels, ncolors) +register Display *dpy; +Colormap cmap; +Bool contig; +unsigned int ncolors; /* CARD16 */ +unsigned int nplanes; /* CARD16 */ +unsigned long *masks; /* LISTofCARD32 */ /* RETURN */ +unsigned long *pixels; /* LISTofCARD32 */ /* RETURN */ +{ + + Status status; + xAllocColorCellsReply rep; + register xAllocColorCellsReq *req; + LockDisplay(dpy); + GetReq(AllocColorCells, req); + + req->cmap = cmap; + req->colors = ncolors; + req->planes = nplanes; + req->contiguous = contig; + + status = _XReply(dpy, (xReply *)&rep, 0, xFalse); + + if (status) { + _XRead32 (dpy, (long *) pixels, 4L * (long) (rep.nPixels)); + _XRead32 (dpy, (long *) masks, 4L * (long) (rep.nMasks)); + } + + UnlockDisplay(dpy); + SyncHandle(); + return(status); +} diff --git a/src/AllPlanes.c b/src/AllPlanes.c new file mode 100644 index 00000000..b636159e --- /dev/null +++ b/src/AllPlanes.c @@ -0,0 +1,70 @@ +/* $Xorg: AllPlanes.c,v 1.4 2001/02/09 02:03:31 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#define NEED_REPLIES +#include "Xlibint.h" + +Status XAllocColorPlanes(dpy, cmap, contig, pixels, ncolors, nreds, ngreens, + nblues, rmask, gmask, bmask) +register Display *dpy; +Colormap cmap; +Bool contig; +unsigned long *pixels; /* LISTofCARD32 */ /* RETURN */ +int ncolors; +int nreds, ngreens, nblues; +unsigned long *rmask, *gmask, *bmask; /* CARD32 */ /* RETURN */ +{ + xAllocColorPlanesReply rep; + Status status; + register xAllocColorPlanesReq *req; + + LockDisplay(dpy); + GetReq(AllocColorPlanes,req); + + req->cmap = cmap; + req->colors = ncolors; + req->red = nreds; + req->green = ngreens; + req->blue = nblues; + req->contiguous = contig; + + status = _XReply(dpy, (xReply *)&rep, 0, xFalse); + + + if (status) { + *rmask = rep.redMask; + *gmask = rep.greenMask; + *bmask = rep.blueMask; + + /* sizeof(CARD32) = 4 */ + _XRead32 (dpy, (char *) pixels, (long)(ncolors * 4)); + } + + UnlockDisplay(dpy); + SyncHandle(); + return(status); +} diff --git a/src/AllowEv.c b/src/AllowEv.c new file mode 100644 index 00000000..b12e8f61 --- /dev/null +++ b/src/AllowEv.c @@ -0,0 +1,48 @@ +/* $Xorg: AllowEv.c,v 1.4 2001/02/09 02:03:31 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XAllowEvents(dpy, mode, time) + register Display *dpy; + int mode; + Time time; + +{ + register xAllowEventsReq *req; + + LockDisplay(dpy); + GetReq(AllowEvents,req); + req->mode = mode; + req->time = time; + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} + + + diff --git a/src/AutoRep.c b/src/AutoRep.c new file mode 100644 index 00000000..beb9a8f1 --- /dev/null +++ b/src/AutoRep.c @@ -0,0 +1,48 @@ +/* $Xorg: AutoRep.c,v 1.4 2001/02/09 02:03:31 xorgcvs Exp $ */ +/* + +Copyright 1985, 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. + +*/ + +#include "Xlibint.h" + +XAutoRepeatOn (dpy) +register Display *dpy; +{ + XKeyboardControl values; + values.auto_repeat_mode = AutoRepeatModeOn; + XChangeKeyboardControl (dpy, KBAutoRepeatMode, &values); + return 1; +} + +XAutoRepeatOff (dpy) +register Display *dpy; +{ + XKeyboardControl values; + values.auto_repeat_mode = AutoRepeatModeOff; + XChangeKeyboardControl (dpy, KBAutoRepeatMode, &values); + return 1; +} + + diff --git a/src/Backgnd.c b/src/Backgnd.c new file mode 100644 index 00000000..e5b67666 --- /dev/null +++ b/src/Backgnd.c @@ -0,0 +1,46 @@ +/* $Xorg: Backgnd.c,v 1.4 2001/02/09 02:03:31 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XSetWindowBackground(dpy, w, pixel) + register Display *dpy; + Window w; + unsigned long pixel; +{ + register xChangeWindowAttributesReq *req; + + LockDisplay(dpy); + GetReqExtra (ChangeWindowAttributes, 4, req); + req->window = w; + req->valueMask = CWBackPixel; + OneDataCard32 (dpy, NEXTPTR(req,xChangeWindowAttributesReq), pixel); + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} + diff --git a/src/BdrWidth.c b/src/BdrWidth.c new file mode 100644 index 00000000..2550fda3 --- /dev/null +++ b/src/BdrWidth.c @@ -0,0 +1,50 @@ +/* $Xorg: BdrWidth.c,v 1.4 2001/02/09 02:03:31 xorgcvs Exp $ */ + +/* + +Copyright 1994, 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. + +*/ + +#include "Xlibint.h" + +XSetWindowBorderWidth(dpy, w, width) +Display *dpy; +Window w; +unsigned int width; +{ + unsigned long lwidth = width; /* must be CARD32 */ + + register xConfigureWindowReq *req; + LockDisplay(dpy); + GetReqExtra(ConfigureWindow, 4, req); + req->window = w; + req->mask = CWBorderWidth; + OneDataCard32 (dpy, NEXTPTR(req,xConfigureWindowReq), lwidth); + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} + diff --git a/src/Bell.c b/src/Bell.c new file mode 100644 index 00000000..7c620206 --- /dev/null +++ b/src/Bell.c @@ -0,0 +1,43 @@ +/* $Xorg: Bell.c,v 1.4 2001/02/09 02:03:31 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XBell(dpy, percent) + register Display *dpy; + int percent; +{ + register xBellReq *req; + + LockDisplay(dpy); + GetReq(Bell,req); + req->percent = percent; + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} + diff --git a/src/Border.c b/src/Border.c new file mode 100644 index 00000000..5e71ee90 --- /dev/null +++ b/src/Border.c @@ -0,0 +1,46 @@ +/* $Xorg: Border.c,v 1.4 2001/02/09 02:03:31 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XSetWindowBorder(dpy, w, pixel) + register Display *dpy; + Window w; + unsigned long pixel; +{ + register xChangeWindowAttributesReq *req; + + LockDisplay(dpy); + GetReqExtra (ChangeWindowAttributes, 4, req); + req->window = w; + req->valueMask = CWBorderPixel; + OneDataCard32 (dpy, NEXTPTR(req,xChangeWindowAttributesReq), pixel); + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} + diff --git a/src/ChAccCon.c b/src/ChAccCon.c new file mode 100644 index 00000000..4366f695 --- /dev/null +++ b/src/ChAccCon.c @@ -0,0 +1,58 @@ +/* $Xorg: ChAccCon.c,v 1.4 2001/02/09 02:03:31 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XEnableAccessControl(dpy) + register Display *dpy; + +{ + return XSetAccessControl(dpy, EnableAccess); +} + +XDisableAccessControl(dpy) + register Display *dpy; + +{ + return XSetAccessControl(dpy, DisableAccess); +} + +XSetAccessControl(dpy, mode) + register Display *dpy; + int mode; + +{ + register xSetAccessControlReq *req; + + LockDisplay(dpy); + GetReq(SetAccessControl, req); + req->mode = mode; + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} + diff --git a/src/ChActPGb.c b/src/ChActPGb.c new file mode 100644 index 00000000..adc2036e --- /dev/null +++ b/src/ChActPGb.c @@ -0,0 +1,46 @@ +/* $Xorg: ChActPGb.c,v 1.4 2001/02/09 02:03:31 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XChangeActivePointerGrab(dpy, event_mask, curs, time) +register Display *dpy; +unsigned int event_mask; /* CARD16 */ +Cursor curs; +Time time; +{ + register xChangeActivePointerGrabReq *req; + + LockDisplay(dpy); + GetReq(ChangeActivePointerGrab, req); + req->eventMask = event_mask; + req->cursor = curs; + req->time = time; + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} diff --git a/src/ChClMode.c b/src/ChClMode.c new file mode 100644 index 00000000..0b2657eb --- /dev/null +++ b/src/ChClMode.c @@ -0,0 +1,44 @@ +/* $Xorg: ChClMode.c,v 1.4 2001/02/09 02:03:31 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XSetCloseDownMode(dpy, mode) + register Display *dpy; + int mode; + +{ + register xSetCloseDownModeReq *req; + + LockDisplay(dpy); + GetReq(SetCloseDownMode, req); + req->mode = mode; + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} + diff --git a/src/ChCmap.c b/src/ChCmap.c new file mode 100644 index 00000000..d6aaa892 --- /dev/null +++ b/src/ChCmap.c @@ -0,0 +1,46 @@ +/* $Xorg: ChCmap.c,v 1.4 2001/02/09 02:03:31 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XSetWindowColormap(dpy, w, colormap) + register Display *dpy; + Window w; + Colormap colormap; +{ + register xChangeWindowAttributesReq *req; + + LockDisplay(dpy); + GetReqExtra (ChangeWindowAttributes, 4, req); + req->window = w; + req->valueMask = CWColormap; + OneDataCard32 (dpy, NEXTPTR(req,xChangeWindowAttributesReq), colormap); + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} + diff --git a/src/ChGC.c b/src/ChGC.c new file mode 100644 index 00000000..d7d536a6 --- /dev/null +++ b/src/ChGC.c @@ -0,0 +1,48 @@ +/* $Xorg: ChGC.c,v 1.4 2001/02/09 02:03:31 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XChangeGC (dpy, gc, valuemask, values) + register Display *dpy; + GC gc; + unsigned long valuemask; + XGCValues *values; +{ + LockDisplay(dpy); + + valuemask &= (1L << (GCLastBit + 1)) - 1; + if (valuemask) _XUpdateGCCache (gc, valuemask, values); + + /* if any Resource ID changed, must flush */ + if (gc->dirty & (GCFont | GCTile | GCStipple)) + _XFlushGCCache(dpy, gc); + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} + diff --git a/src/ChKeyCon.c b/src/ChKeyCon.c new file mode 100644 index 00000000..c1b3fdce --- /dev/null +++ b/src/ChKeyCon.c @@ -0,0 +1,80 @@ +/* $Xorg: ChKeyCon.c,v 1.4 2001/02/09 02:03:31 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XChangeKeyboardControl(dpy, mask, value_list) + register Display *dpy; + unsigned long mask; + XKeyboardControl *value_list; +{ + unsigned long values[8]; + register unsigned long *value = values; + long nvalues; + register xChangeKeyboardControlReq *req; + + LockDisplay(dpy); + GetReq(ChangeKeyboardControl, req); + req->mask = mask; + + if (mask & KBKeyClickPercent) + *value++ = value_list->key_click_percent; + + if (mask & KBBellPercent) + *value++ = value_list->bell_percent; + + if (mask & KBBellPitch) + *value++ = value_list->bell_pitch; + + if (mask & KBBellDuration) + *value++ = value_list->bell_duration; + + if (mask & KBLed) + *value++ = value_list->led; + + if (mask & KBLedMode) + *value++ = value_list->led_mode; + + if (mask & KBKey) + *value++ = value_list->key; + + if (mask & KBAutoRepeatMode) + *value++ = value_list->auto_repeat_mode; + + + req->length += (nvalues = value - values); + + /* note: Data is a macro that uses its arguments multiple + times, so "nvalues" is changed in a separate assignment + statement */ + + nvalues <<= 2; + Data32 (dpy, (long *) values, nvalues); + UnlockDisplay(dpy); + SyncHandle(); + return 1; + } diff --git a/src/ChPntCon.c b/src/ChPntCon.c new file mode 100644 index 00000000..ce0776d9 --- /dev/null +++ b/src/ChPntCon.c @@ -0,0 +1,50 @@ +/* $Xorg: ChPntCon.c,v 1.4 2001/02/09 02:03:31 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XChangePointerControl(dpy, do_acc, do_thresh, acc_numerator, + acc_denominator, threshold) + register Display *dpy; + Bool do_acc, do_thresh; + int acc_numerator, acc_denominator, threshold; + +{ + register xChangePointerControlReq *req; + + LockDisplay(dpy); + GetReq(ChangePointerControl, req); + req->doAccel = do_acc; + req->doThresh = do_thresh; + req->accelNum = acc_numerator; + req->accelDenum = acc_denominator; + req->threshold = threshold; + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} + diff --git a/src/ChProp.c b/src/ChProp.c new file mode 100644 index 00000000..4cfbe96d --- /dev/null +++ b/src/ChProp.c @@ -0,0 +1,107 @@ +/* $Xorg: ChProp.c,v 1.4 2001/02/09 02:03:31 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +#if NeedFunctionPrototypes +XChangeProperty ( + register Display *dpy, + Window w, + Atom property, + Atom type, + int format, /* 8, 16, or 32 */ + int mode, /* PropModeReplace, PropModePrepend, PropModeAppend */ + _Xconst unsigned char *data, + int nelements) +#else +XChangeProperty (dpy, w, property, type, format, mode, data, nelements) + register Display *dpy; + Window w; + Atom property, type; + int format; /* 8, 16, or 32 */ + int mode; /* PropModeReplace, PropModePrepend, PropModeAppend */ + unsigned char *data; + int nelements; +#endif + { + register xChangePropertyReq *req; + register long len; + + LockDisplay(dpy); + GetReq (ChangeProperty, req); + req->window = w; + req->property = property; + req->type = type; + req->mode = mode; + if (nelements < 0) { + req->nUnits = 0; + req->format = 0; /* ask for garbage, get garbage */ + } else { + req->nUnits = nelements; + req->format = format; + } + + switch (req->format) { + case 8: + len = ((long)nelements + 3)>>2; + if (dpy->bigreq_size || req->length + len <= (unsigned) 65535) { + SetReqLen(req, len, len); + Data (dpy, (char *)data, nelements); + } /* else force BadLength */ + break; + + case 16: + len = ((long)nelements + 1)>>1; + if (dpy->bigreq_size || req->length + len <= (unsigned) 65535) { + SetReqLen(req, len, len); + len = (long)nelements << 1; + Data16 (dpy, (short *) data, len); + } /* else force BadLength */ + break; + + case 32: + len = nelements; + if (dpy->bigreq_size || req->length + len <= (unsigned) 65535) { + SetReqLen(req, len, len); + len = (long)nelements << 2; + Data32 (dpy, (long *) data, len); + } /* else force BadLength */ + break; + + default: + /* BadValue will be generated */ ; + } + + UnlockDisplay(dpy); + SyncHandle(); + return 1; + } + + + + + diff --git a/src/ChSaveSet.c b/src/ChSaveSet.c new file mode 100644 index 00000000..7adb08cf --- /dev/null +++ b/src/ChSaveSet.c @@ -0,0 +1,58 @@ +/* $Xorg: ChSaveSet.c,v 1.4 2001/02/09 02:03:31 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XChangeSaveSet(dpy, win, mode) +register Display *dpy; +Window win; +int mode; +{ + register xChangeSaveSetReq *req; + + LockDisplay(dpy); + GetReq(ChangeSaveSet, req); + req->window = win; + req->mode = mode; + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} + +XAddToSaveSet(dpy, win) + register Display *dpy; + Window win; +{ + return XChangeSaveSet(dpy,win,SetModeInsert); +} + +XRemoveFromSaveSet (dpy, win) + register Display *dpy; + Window win; +{ + return XChangeSaveSet(dpy,win,SetModeDelete); +} diff --git a/src/ChWAttrs.c b/src/ChWAttrs.c new file mode 100644 index 00000000..2c05cf55 --- /dev/null +++ b/src/ChWAttrs.c @@ -0,0 +1,55 @@ +/* $Xorg: ChWAttrs.c,v 1.5 2001/02/09 02:03:31 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +#define AllMaskBits (CWBackPixmap|CWBackPixel|CWBorderPixmap|\ + CWBorderPixel|CWBitGravity|CWWinGravity|\ + CWBackingStore|CWBackingPlanes|CWBackingPixel|\ + CWOverrideRedirect|CWSaveUnder|CWEventMask|\ + CWDontPropagate|CWColormap|CWCursor) + +XChangeWindowAttributes (dpy, w, valuemask, attributes) + register Display *dpy; + Window w; + unsigned long valuemask; + XSetWindowAttributes *attributes; +{ + register xChangeWindowAttributesReq *req; + extern void _XProcessWindowAttributes(); + + LockDisplay(dpy); + GetReq(ChangeWindowAttributes,req); + req->window = w; + valuemask &= AllMaskBits; + if ((req->valueMask = valuemask)) + _XProcessWindowAttributes (dpy, req, valuemask, attributes); + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} + diff --git a/src/ChWindow.c b/src/ChWindow.c new file mode 100644 index 00000000..b0319aa6 --- /dev/null +++ b/src/ChWindow.c @@ -0,0 +1,59 @@ +/* $Xorg: ChWindow.c,v 1.4 2001/02/09 02:03:31 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XResizeWindow(dpy, w, width, height) +register Display *dpy; +Window w; +unsigned int width, height; +{ + register xConfigureWindowReq *req; + + LockDisplay(dpy); + GetReqExtra(ConfigureWindow, 8, req); /* 2 4-byte quantities */ + + req->window = w; + req->mask = CWWidth | CWHeight; +#ifdef MUSTCOPY + { + unsigned long lwidth = width, lheight = height; + dpy->bufptr -= 8; + Data32 (dpy, (long *) &lwidth, 4); /* order dictated by values of */ + Data32 (dpy, (long *) &lheight, 4); /* CWWidth and CWHeight */ + } +#else + { + CARD32 *valuePtr = (CARD32 *) NEXTPTR(req,xConfigureWindowReq); + *valuePtr++ = width; + *valuePtr = height; + } +#endif /* MUSTCOPY */ + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} diff --git a/src/ChkIfEv.c b/src/ChkIfEv.c new file mode 100644 index 00000000..24539e82 --- /dev/null +++ b/src/ChkIfEv.c @@ -0,0 +1,83 @@ +/* $Xorg: ChkIfEv.c,v 1.4 2001/02/09 02:03:31 xorgcvs Exp $ */ +/* + +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. + +*/ + +#define NEED_EVENTS +#include "Xlibint.h" + +/* + * Check existing events in queue to find if any match. If so, return. + * If not, flush buffer and see if any more events are readable. If one + * matches, return. If all else fails, tell the user no events found. + */ + +Bool XCheckIfEvent (dpy, event, predicate, arg) + register Display *dpy; + Bool (*predicate)( +#if NeedNestedPrototypes + Display* /* display */, + XEvent* /* event */, + char* /* arg */ +#endif + ); /* function to call */ + register XEvent *event; /* XEvent to be filled in. */ + char *arg; +{ + register _XQEvent *prev, *qelt; + unsigned long qe_serial = 0; + int n; /* time through count */ + + LockDisplay(dpy); + prev = NULL; + for (n = 3; --n >= 0;) { + for (qelt = prev ? prev->next : dpy->head; + qelt; + prev = qelt, qelt = qelt->next) { + if(qelt->qserial_num > qe_serial + && (*predicate)(dpy, &qelt->event, arg)) { + *event = qelt->event; + _XDeq(dpy, prev, qelt); + UnlockDisplay(dpy); + return True; + } + } + if (prev) + qe_serial = prev->qserial_num; + switch (n) { + case 2: + _XEventsQueued(dpy, QueuedAfterReading); + break; + case 1: + _XFlush(dpy); + break; + } + if (prev && prev->qserial_num != qe_serial) + /* another thread has snatched this event */ + prev = NULL; + } + UnlockDisplay(dpy); + return False; +} diff --git a/src/ChkMaskEv.c b/src/ChkMaskEv.c new file mode 100644 index 00000000..cc511720 --- /dev/null +++ b/src/ChkMaskEv.c @@ -0,0 +1,90 @@ +/* $Xorg: ChkMaskEv.c,v 1.4 2001/02/09 02:03:31 xorgcvs Exp $ */ +/* + +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. + +*/ + +#define NEED_EVENTS +#include "Xlibint.h" + +#ifdef __STDC__ +#define Const const +#else +#define Const /**/ +#endif +extern long Const _Xevent_to_mask[]; + +#define AllPointers (PointerMotionMask|PointerMotionHintMask|ButtonMotionMask) +#define AllButtons (Button1MotionMask|Button2MotionMask|Button3MotionMask|\ + Button4MotionMask|Button5MotionMask) + +/* + * Check existing events in queue to find if any match. If so, return. + * If not, flush buffer and see if any more events are readable. If one + * matches, return. If all else fails, tell the user no events found. + */ + +Bool XCheckMaskEvent (dpy, mask, event) + register Display *dpy; + long mask; /* Selected event mask. */ + register XEvent *event; /* XEvent to be filled in. */ +{ + register _XQEvent *prev, *qelt; + unsigned long qe_serial; + int n; /* time through count */ + + LockDisplay(dpy); + prev = NULL; + for (n = 3; --n >= 0;) { + for (qelt = prev ? prev->next : dpy->head; + qelt; + prev = qelt, qelt = qelt->next) { + if ((qelt->event.type < LASTEvent) && + (_Xevent_to_mask[qelt->event.type] & mask) && + ((qelt->event.type != MotionNotify) || + (mask & AllPointers) || + (mask & AllButtons & qelt->event.xmotion.state))) { + *event = qelt->event; + _XDeq(dpy, prev, qelt); + UnlockDisplay(dpy); + return True; + } + } + if (prev) + qe_serial = prev->qserial_num; + switch (n) { + case 2: + _XEventsQueued(dpy, QueuedAfterReading); + break; + case 1: + _XFlush(dpy); + break; + } + if (prev && prev->qserial_num != qe_serial) + /* another thread has snatched this event */ + prev = NULL; + } + UnlockDisplay(dpy); + return False; +} diff --git a/src/ChkTypEv.c b/src/ChkTypEv.c new file mode 100644 index 00000000..dd45be0b --- /dev/null +++ b/src/ChkTypEv.c @@ -0,0 +1,75 @@ +/* $Xorg: ChkTypEv.c,v 1.4 2001/02/09 02:03:31 xorgcvs Exp $ */ +/* + +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. + +*/ + +#define NEED_EVENTS +#include "Xlibint.h" + +/* + * Check existing events in queue to find if any match. If so, return. + * If not, flush buffer and see if any more events are readable. If one + * matches, return. If all else fails, tell the user no events found. + */ + +Bool XCheckTypedEvent (dpy, type, event) + register Display *dpy; + int type; /* Selected event type. */ + register XEvent *event; /* XEvent to be filled in. */ +{ + register _XQEvent *prev, *qelt; + unsigned long qe_serial; + int n; /* time through count */ + + LockDisplay(dpy); + prev = NULL; + for (n = 3; --n >= 0;) { + for (qelt = prev ? prev->next : dpy->head; + qelt; + prev = qelt, qelt = qelt->next) { + if (qelt->event.type == type) { + *event = qelt->event; + _XDeq(dpy, prev, qelt); + UnlockDisplay(dpy); + return True; + } + } + if (prev) + qe_serial = prev->qserial_num; + switch (n) { + case 2: + _XEventsQueued(dpy, QueuedAfterReading); + break; + case 1: + _XFlush(dpy); + break; + } + if (prev && prev->qserial_num != qe_serial) + /* another thread has snatched this event */ + prev = NULL; + } + UnlockDisplay(dpy); + return False; +} diff --git a/src/ChkTypWEv.c b/src/ChkTypWEv.c new file mode 100644 index 00000000..09b48b5d --- /dev/null +++ b/src/ChkTypWEv.c @@ -0,0 +1,77 @@ +/* $Xorg: ChkTypWEv.c,v 1.4 2001/02/09 02:03:31 xorgcvs Exp $ */ +/* + +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. + +*/ + +#define NEED_EVENTS +#include "Xlibint.h" + +/* + * Check existing events in queue to find if any match. If so, return. + * If not, flush buffer and see if any more events are readable. If one + * matches, return. If all else fails, tell the user no events found. + */ + +Bool XCheckTypedWindowEvent (dpy, w, type, event) + register Display *dpy; + Window w; /* Selected window. */ + int type; /* Selected event type. */ + register XEvent *event; /* XEvent to be filled in. */ +{ + register _XQEvent *prev, *qelt; + unsigned long qe_serial; + int n; /* time through count */ + + LockDisplay(dpy); + prev = NULL; + for (n = 3; --n >= 0;) { + for (qelt = prev ? prev->next : dpy->head; + qelt; + prev = qelt, qelt = qelt->next) { + if ((qelt->event.xany.window == w) && + (qelt->event.type == type)) { + *event = qelt->event; + _XDeq(dpy, prev, qelt); + UnlockDisplay(dpy); + return True; + } + } + if (prev) + qe_serial = prev->qserial_num; + switch (n) { + case 2: + _XEventsQueued(dpy, QueuedAfterReading); + break; + case 1: + _XFlush(dpy); + break; + } + if (prev && prev->qserial_num != qe_serial) + /* another thread has snatched this event */ + prev = NULL; + } + UnlockDisplay(dpy); + return False; +} diff --git a/src/ChkWinEv.c b/src/ChkWinEv.c new file mode 100644 index 00000000..27d4c05e --- /dev/null +++ b/src/ChkWinEv.c @@ -0,0 +1,91 @@ +/* $Xorg: ChkWinEv.c,v 1.4 2001/02/09 02:03:31 xorgcvs Exp $ */ +/* + +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. + +*/ + +#define NEED_EVENTS +#include "Xlibint.h" + +#ifdef __STDC__ +#define Const const +#else +#define Const /**/ +#endif +extern long Const _Xevent_to_mask[]; +#define AllPointers (PointerMotionMask|PointerMotionHintMask|ButtonMotionMask) +#define AllButtons (Button1MotionMask|Button2MotionMask|Button3MotionMask|\ + Button4MotionMask|Button5MotionMask) + +/* + * Check existing events in queue to find if any match. If so, return. + * If not, flush buffer and see if any more events are readable. If one + * matches, return. If all else fails, tell the user no events found. + */ + +Bool XCheckWindowEvent (dpy, w, mask, event) + register Display *dpy; + Window w; /* Selected window. */ + long mask; /* Selected event mask. */ + register XEvent *event; /* XEvent to be filled in. */ +{ + register _XQEvent *prev, *qelt; + unsigned long qe_serial; + int n; /* time through count */ + + LockDisplay(dpy); + prev = NULL; + for (n = 3; --n >= 0;) { + for (qelt = prev ? prev->next : dpy->head; + qelt; + prev = qelt, qelt = qelt->next) { + if ((qelt->event.xany.window == w) && + (qelt->event.type < LASTEvent) && + (_Xevent_to_mask[qelt->event.type] & mask) && + ((qelt->event.type != MotionNotify) || + (mask & AllPointers) || + (mask & AllButtons & qelt->event.xmotion.state))) { + *event = qelt->event; + _XDeq(dpy, prev, qelt); + UnlockDisplay(dpy); + return True; + } + } + if (prev) + qe_serial = prev->qserial_num; + switch (n) { + case 2: + _XEventsQueued(dpy, QueuedAfterReading); + break; + case 1: + _XFlush(dpy); + break; + } + if (prev && prev->qserial_num != qe_serial) + /* another thread has snatched this event */ + prev = NULL; + } + UnlockDisplay(dpy); + return False; +} diff --git a/src/CirWin.c b/src/CirWin.c new file mode 100644 index 00000000..4099900f --- /dev/null +++ b/src/CirWin.c @@ -0,0 +1,45 @@ +/* $Xorg: CirWin.c,v 1.4 2001/02/09 02:03:31 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XCirculateSubwindows(dpy, w, direction) + register Display *dpy; + Window w; + int direction; +{ + register xCirculateWindowReq *req; + + LockDisplay(dpy); + GetReq(CirculateWindow, req); + req->window = w; + req->direction = direction; + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} + diff --git a/src/CirWinDn.c b/src/CirWinDn.c new file mode 100644 index 00000000..c3dce796 --- /dev/null +++ b/src/CirWinDn.c @@ -0,0 +1,44 @@ +/* $Xorg: CirWinDn.c,v 1.4 2001/02/09 02:03:31 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XCirculateSubwindowsDown(dpy,w) + register Display *dpy; + Window w; +{ + register xCirculateWindowReq *req; + + LockDisplay(dpy); + GetReq(CirculateWindow, req); + req->window = w; + req->direction = LowerHighest; + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} + diff --git a/src/CirWinUp.c b/src/CirWinUp.c new file mode 100644 index 00000000..65ff8645 --- /dev/null +++ b/src/CirWinUp.c @@ -0,0 +1,44 @@ +/* $Xorg: CirWinUp.c,v 1.4 2001/02/09 02:03:31 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XCirculateSubwindowsUp(dpy, w) + register Display *dpy; + Window w; +{ + register xCirculateWindowReq *req; + + LockDisplay(dpy); + GetReq(CirculateWindow, req); + req->window = w; + req->direction = RaiseLowest; + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} + diff --git a/src/ClDisplay.c b/src/ClDisplay.c new file mode 100644 index 00000000..0ea2fc54 --- /dev/null +++ b/src/ClDisplay.c @@ -0,0 +1,70 @@ +/* $Xorg: ClDisplay.c,v 1.4 2001/02/09 02:03:31 xorgcvs Exp $ */ + +/* + +Copyright 1985, 1990, 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. + +*/ + +#include "Xlibint.h" + +extern void _XFreeDisplayStructure(); + +/* + * XCloseDisplay - XSync the connection to the X Server, close the connection, + * and free all associated storage. Extension close procs should only free + * memory and must be careful about the types of requests they generate. + */ + +XCloseDisplay (dpy) + register Display *dpy; +{ + register _XExtension *ext; + register int i; + + if (!(dpy->flags & XlibDisplayClosing)) + { + dpy->flags |= XlibDisplayClosing; + for (i = 0; i < dpy->nscreens; i++) { + register Screen *sp = &dpy->screens[i]; + XFreeGC (dpy, sp->default_gc); + } + if (dpy->cursor_font != None) { + XUnloadFont (dpy, dpy->cursor_font); + } + XSync(dpy, 1); /* throw away pending events, catch errors */ + /* call out to any extensions interested */ + for (ext = dpy->ext_procs; ext; ext = ext->next) { + if (ext->close_display) + (*ext->close_display)(dpy, &ext->codes); + } + /* if the closes generated more protocol, sync them up */ + if (dpy->request != dpy->last_request_read) + XSync(dpy, 1); + } + _XDisconnectDisplay(dpy->trans_conn); + _XFreeDisplayStructure (dpy); + return 0; +} diff --git a/src/Clear.c b/src/Clear.c new file mode 100644 index 00000000..54fde13e --- /dev/null +++ b/src/Clear.c @@ -0,0 +1,46 @@ +/* $Xorg: Clear.c,v 1.4 2001/02/09 02:03:31 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XClearWindow(dpy, w) + register Display *dpy; + Window w; +{ + register xClearAreaReq *req; + + LockDisplay(dpy); + GetReq(ClearArea, req); + req->window = w; + req->x = req->y = req->width = req->height = 0; + /* these values mean "clear the entire window" */ + req->exposures = xFalse; + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} + diff --git a/src/ClearArea.c b/src/ClearArea.c new file mode 100644 index 00000000..4028ae44 --- /dev/null +++ b/src/ClearArea.c @@ -0,0 +1,51 @@ +/* $Xorg: ClearArea.c,v 1.4 2001/02/09 02:03:31 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XClearArea (dpy, w, x, y, width, height, exposures) + register Display *dpy; + Window w; + int x, y; + unsigned int width, height; + Bool exposures; +{ + register xClearAreaReq *req; + + LockDisplay(dpy); + GetReq(ClearArea, req); + req->window = w; + req->x = x; + req->y = y; + req->width = width; + req->height = height; + req->exposures = exposures; + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} + diff --git a/src/ConfWind.c b/src/ConfWind.c new file mode 100644 index 00000000..f4bb4239 --- /dev/null +++ b/src/ConfWind.c @@ -0,0 +1,66 @@ +/* $Xorg: ConfWind.c,v 1.4 2001/02/09 02:03:31 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XMoveResizeWindow(dpy, w, x, y, width, height) +register Display *dpy; +Window w; +int x, y; +unsigned int width, height; +{ + register xConfigureWindowReq *req; + + LockDisplay(dpy); + GetReqExtra(ConfigureWindow, 16, req); + req->window = w; + req->mask = CWX | CWY | CWWidth | CWHeight; +#ifdef MUSTCOPY + { + long lx = x, ly = y; + unsigned long lwidth = width, lheight = height; + + dpy->bufptr -= 16; + Data32 (dpy, (long *) &lx, 4); /* order must match values of */ + Data32 (dpy, (long *) &ly, 4); /* CWX, CWY, CWWidth, and CWHeight */ + Data32 (dpy, (long *) &lwidth, 4); + Data32 (dpy, (long *) &lheight, 4); + } +#else + { + register CARD32 *valuePtr = + (CARD32 *) NEXTPTR(req,xConfigureWindowReq); + *valuePtr++ = x; + *valuePtr++ = y; + *valuePtr++ = width; + *valuePtr = height; + } +#endif /* MUSTCOPY */ + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} diff --git a/src/ConnDis.c b/src/ConnDis.c new file mode 100644 index 00000000..9ee55118 --- /dev/null +++ b/src/ConnDis.c @@ -0,0 +1,1157 @@ +/* $Xorg: ConnDis.c,v 1.8 2001/02/09 02:03:31 xorgcvs Exp $ */ +/* + +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 file contains operating system dependencies. + */ + +#define NEED_EVENTS + +#include <X11/Xlibint.h> +#include <X11/Xtrans.h> +#include <X11/Xauth.h> +#include <stdio.h> +#include <ctype.h> + +#ifndef WIN32 +#include <sys/socket.h> +#endif + +#ifndef X_CONNECTION_RETRIES /* number retries on ECONNREFUSED */ +#define X_CONNECTION_RETRIES 5 +#endif + +#ifdef LOCALCONN +#include <sys/utsname.h> +#endif + +static void GetAuthorization(); + +static char *copystring (src, len) + char *src; + int len; +{ + char *dst = Xmalloc (len + 1); + + if (dst) { + strncpy (dst, src, len); + dst[len] = '\0'; + } + + return dst; +} + + +/* + * Attempts to connect to server, given display name. Returns file descriptor + * (network socket) or -1 if connection fails. Display names may be of the + * following format: + * + * [protocol/] [hostname] : [:] displaynumber [.screennumber] + * + * The second colon indicates a DECnet style name. No hostname is interpretted + * as the most efficient local connection to a server on the same machine. + * This is usually: + * + * o shared memory + * o local stream + * o UNIX domain socket + * o TCP to local host + * + * This function will eventually call the X Transport Interface functions + * which expects the hostname in the format: + * + * [protocol/] [hostname] : [:] displaynumber + * + */ +XtransConnInfo +_X11TransConnectDisplay (display_name, fullnamep, dpynump, screenp, + auth_namep, auth_namelenp, auth_datap, auth_datalenp) + char *display_name; + char **fullnamep; /* RETURN */ + int *dpynump; /* RETURN */ + int *screenp; /* RETURN */ + char **auth_namep; /* RETURN */ + int *auth_namelenp; /* RETURN */ + char **auth_datap; /* RETURN */ + int *auth_datalenp; /* RETURN */ +{ + int family; + int saddrlen; + Xtransaddr *saddr; + char *lastp, *lastc, *p; /* char pointers */ + char *pprotocol = NULL; /* start of protocol name */ + char *phostname = NULL; /* start of host of display */ + char *pdpynum = NULL; /* start of dpynum of display */ + char *pscrnum = NULL; /* start of screen of display */ + Bool dnet = False; /* if true, then DECnet format */ + int idisplay; /* required display number */ + int iscreen = 0; /* optional screen number */ + int (*connfunc)(); /* method to create connection */ + int len, hostlen; /* length tmp variable */ + int retry; /* retry counter */ + char addrbuf[128]; /* final address passed to + X Transport Interface */ + char* address = addrbuf; + XtransConnInfo trans_conn = NULL; /* transport connection object */ + int connect_stat; +#ifdef LOCALCONN + struct utsname sys; +#ifdef TCPCONN + char *tcphostname = NULL; /* A place to save hostname pointer */ +#endif +#endif + + p = display_name; + + saddrlen = 0; /* set so that we can clear later */ + saddr = NULL; + + /* + * Step 0, find the protocol. This is delimited by the optional + * slash ('/'). + */ + for (lastp = p; *p && *p != ':' && *p != '/'; p++) ; + if (!*p) return NULL; /* must have a colon */ + + if (p != lastp && *p != ':') { /* protocol given? */ + pprotocol = copystring (lastp, p - lastp); + if (!pprotocol) goto bad; /* no memory */ + p++; /* skip the '/' */ + } else + p = display_name; /* reset the pointer in + case no protocol was given */ + + /* + * Step 1, find the hostname. This is delimited by either one colon, + * or two colons in the case of DECnet (DECnet Phase V allows a single + * colon in the hostname). + */ + + lastp = p; + lastc = NULL; + for (; *p; p++) + if (*p == ':') + lastc = p; + + if (!lastc) return NULL; /* must have a colon */ + + if ((lastp != lastc) && (*(lastc - 1) == ':')) { + /* DECnet display specified */ + +#ifndef DNETCONN + goto bad; +#else + dnet = True; + /* override the protocol specified */ + if (pprotocol) + Xfree (pprotocol); + pprotocol = copystring ("dnet", 4); + hostlen = lastc - 1 - lastp; +#endif + } + else + hostlen = lastc - lastp; + + if (hostlen > 0) { /* hostname given? */ + phostname = copystring (lastp, hostlen); + if (!phostname) goto bad; /* no memory */ + } + + p = lastc; + +#ifdef LOCALCONN + /* check if phostname == localnodename AND protocol not specified */ + if (!pprotocol && phostname && uname(&sys) >= 0 && + !strncmp(phostname, sys.nodename, + (strlen(sys.nodename) < strlen(phostname) ? + strlen(phostname) : strlen(sys.nodename)))) + { +#ifdef TCPCONN + /* + * We'll first attempt to connect using the local transport. If + * this fails (which is the case if sshd X protocol forwarding is + * being used), retry using tcp and this hostname. + */ + tcphostname = copystring(phostname, strlen(phostname)); +#endif + Xfree (phostname); + phostname = copystring ("unix", 4); + } +#endif + + + /* + * Step 2, find the display number. This field is required and is + * delimited either by a nul or a period, depending on whether or not + * a screen number is present. + */ + + for (lastp = ++p; *p && isascii(*p) && isdigit(*p); p++) ; + if ((p == lastp) || /* required field */ + (*p != '\0' && *p != '.') || /* invalid non-digit terminator */ + !(pdpynum = copystring (lastp, p - lastp))) /* no memory */ + goto bad; + idisplay = atoi (pdpynum); + + + /* + * Step 3, find the screen number. This field is optional. It is + * present only if the display number was followed by a period (which + * we've already verified is the only non-nul character). + */ + + if (*p) { + for (lastp = ++p; *p && isascii(*p) && isdigit (*p); p++) ; + if (p != lastp) { + if (*p || /* non-digits */ + !(pscrnum = copystring (lastp, p - lastp))) /* no memory */ + goto bad; + iscreen = atoi (lastp); + } + } + + /* + * At this point, we know the following information: + * + * pprotocol protocol string or NULL + * phostname hostname string or NULL + * idisplay display number + * iscreen screen number + * dnet DECnet boolean + * + * We can now decide which transport to use based on the ConnectionFlags + * build parameter the hostname string. If phostname is NULL or equals + * the string "local", then choose the best transport. If phostname + * is "unix", then choose BSD UNIX domain sockets (if configured). + */ + +#if defined(TCPCONN) || defined(UNIXCONN) || defined(LOCALCONN) + if (!pprotocol) { + if (!phostname) +#if defined(UNIXCONN) || defined(LOCALCONN) + pprotocol = copystring ("local", 5); + else +#endif + pprotocol = copystring ("tcp", 3); + } +#endif + +#if defined(UNIXCONN) || defined(LOCALCONN) + /* + * Now that the defaults have been established, see if we have any + * special names that we have to override: + * + * :N => if UNIXCONN then unix-domain-socket + * ::N => if UNIXCONN then unix-domain-socket + * unix:N => if UNIXCONN then unix-domain-socket + * + * Note that if UNIXCONN isn't defined, then we can use the default + * transport connection function set above. + */ + + if (!phostname) { +#ifdef apollo + ; /* Unix domain sockets are *really* bad on apollos */ +#else + if( pprotocol ) Xfree(pprotocol); + pprotocol = copystring ("local", 5); +#endif + } + else if (strcmp (phostname, "unix") == 0) { + if( pprotocol ) Xfree(pprotocol); + pprotocol = copystring ("local", 5); + } +#endif + + connect: + /* + * This seems kind of backwards, but we need to put the protocol, + * host, and port back together to pass to _X11TransOpenCOTSClient(). + */ + + { + int olen = 3 + (pprotocol ? strlen(pprotocol) : 0) + + (phostname ? strlen(phostname) : 0) + + (pdpynum ? strlen(pdpynum) : 0); + if (olen > sizeof addrbuf) address = Xmalloc (olen); + } + + sprintf(address,"%s/%s:%s", + pprotocol ? pprotocol : "", + phostname ? phostname : "", + pdpynum ); + + /* + * Make the connection, also need to get the auth address info for + * the connection. Do retries in case server host has hit its + * backlog (which, unfortunately, isn't distinguishable from there not + * being a server listening at all, which is why we have to not retry + * too many times). + */ + for(retry=X_CONNECTION_RETRIES; retry>=0; retry-- ) + { + if ( (trans_conn = _X11TransOpenCOTSClient(address)) == NULL ) + { + break; + } + if ((connect_stat = _X11TransConnect(trans_conn,address)) < 0 ) + { + _X11TransClose(trans_conn); + trans_conn = NULL; + + if (connect_stat == TRANS_TRY_CONNECT_AGAIN) + { + sleep(1); + continue; + } + else + break; + } + + _X11TransGetPeerAddr(trans_conn, &family, &saddrlen, &saddr); + + /* + * The family is given in a socket format (ie AF_INET). This + * will convert it to the format used by the authorization and + * X protocol (ie FamilyInternet). + */ + + if( _X11TransConvertAddress(&family, &saddrlen, &saddr) < 0 ) + { + _X11TransClose(trans_conn); + trans_conn = NULL; + sleep(1); + if (saddr) + { + free ((char *) saddr); + saddr = NULL; + } + continue; + } + + break; + } + + if (address != addrbuf) Xfree (address); + + if( trans_conn == NULL ) + goto bad; + + /* + * Set close-on-exec so that programs that fork() doesn't get confused. + */ + + _X11TransSetOption(trans_conn,TRANS_CLOSEONEXEC,1); + + /* + * Build the expanded display name: + * + * [host] : [:] dpy . scr \0 + */ + len = ((phostname ? strlen(phostname) : 0) + 1 + (dnet ? 1 : 0) + + strlen(pdpynum) + 1 + (pscrnum ? strlen(pscrnum) : 1) + 1); + *fullnamep = (char *) Xmalloc (len); + if (!*fullnamep) goto bad; + + sprintf (*fullnamep, "%s%s%d.%d", + (phostname ? phostname : ""), + (dnet ? "::" : ":"), + idisplay, iscreen); + + *dpynump = idisplay; + *screenp = iscreen; + if (pprotocol) Xfree (pprotocol); + if (phostname) Xfree (phostname); + if (pdpynum) Xfree (pdpynum); + if (pscrnum) Xfree (pscrnum); + + GetAuthorization(trans_conn, family, (char *) saddr, saddrlen, idisplay, + auth_namep, auth_namelenp, auth_datap, auth_datalenp); + return trans_conn; + + + /* + * error return; make sure everything is cleaned up. + */ + bad: + if (trans_conn) (void)_X11TransClose(trans_conn); + if (saddr) free ((char *) saddr); + if (pprotocol) Xfree (pprotocol); + if (phostname) Xfree (phostname); + +#if defined(LOCALCONN) && defined(TCPCONN) + if (tcphostname) { + pprotocol = copystring("tcp", 3); + phostname = tcphostname; + tcphostname = NULL; + goto connect; + } +#endif + + if (pdpynum) Xfree (pdpynum); + if (pscrnum) Xfree (pscrnum); + return NULL; + +} + +/* + * This is gross, but we need it for compatiblity. + * The test suite relies on the following interface. + * + */ + +int _XConnectDisplay (display_name, fullnamep, dpynump, screenp, + auth_namep, auth_namelenp, auth_datap, auth_datalenp) + char *display_name; + char **fullnamep; /* RETURN */ + int *dpynump; /* RETURN */ + int *screenp; /* RETURN */ + char **auth_namep; /* RETURN */ + int *auth_namelenp; /* RETURN */ + char **auth_datap; /* RETURN */ + int *auth_datalenp; /* RETURN */ +{ + XtransConnInfo trans_conn; + + trans_conn = _X11TransConnectDisplay ( + display_name, fullnamep, dpynump, screenp, + auth_namep, auth_namelenp, auth_datap, auth_datalenp); + + if (trans_conn) + { + int fd = _X11TransGetConnectionNumber (trans_conn); + _X11TransFreeConnInfo (trans_conn); + return (fd); + } + else + return (-1); +} + + +/***************************************************************************** + * * + * Connection Utility Routines * + * * + *****************************************************************************/ + +/* + * Disconnect from server. + */ + +int _XDisconnectDisplay (trans_conn) + +XtransConnInfo trans_conn; + +{ + _X11TransDisconnect(trans_conn); + _X11TransClose(trans_conn); + return 0; +} + + + +static int padlength[4] = {0, 3, 2, 1}; /* make sure auth is multiple of 4 */ + +Bool +_XSendClientPrefix (dpy, client, auth_proto, auth_string, prefix) + Display *dpy; + xConnClientPrefix *client; /* contains count for auth_* */ + char *auth_proto, *auth_string; /* NOT null-terminated */ + xConnSetupPrefix *prefix; /* prefix information */ +{ + int auth_length = client->nbytesAuthProto; + int auth_strlen = client->nbytesAuthString; + char padbuf[3]; /* for padding to 4x bytes */ + int pad; + struct iovec iovarray[5], *iov = iovarray; + int niov = 0; + int len = 0; + +#define add_to_iov(b,l) \ + { iov->iov_base = (b); iov->iov_len = (l); iov++, niov++; len += (l); } + + add_to_iov ((caddr_t) client, SIZEOF(xConnClientPrefix)); + + /* + * write authorization protocol name and data + */ + if (auth_length > 0) { + add_to_iov (auth_proto, auth_length); + pad = padlength [auth_length & 3]; + if (pad) add_to_iov (padbuf, pad); + } + if (auth_strlen > 0) { + add_to_iov (auth_string, auth_strlen); + pad = padlength [auth_strlen & 3]; + if (pad) add_to_iov (padbuf, pad); + } + +#undef add_to_iov + + len -= _X11TransWritev (dpy->trans_conn, iovarray, niov); + + /* + * Set the connection non-blocking since we use select() to block. + */ + + _X11TransSetOption(dpy->trans_conn, TRANS_NONBLOCKING, 1); + + if (len != 0) + return -1; + +#ifdef K5AUTH + if (auth_length == 14 && + !strncmp(auth_proto, "MIT-KERBEROS-5", 14)) + { + return k5_clientauth(dpy, prefix); + } else +#endif + return 0; +} + + +#ifdef STREAMSCONN +#ifdef SVR4 +#include <tiuser.h> +#else +#undef HASXDMAUTH +#endif +#endif + +#ifdef SECURE_RPC +#include <rpc/rpc.h> +#ifdef ultrix +#include <time.h> +#include <rpc/auth_des.h> +#endif +#endif + +#ifdef HASXDMAUTH +#ifdef X_NOT_STDC_ENV +#define Time_t long +extern Time_t time (); +#else +#include <time.h> +#define Time_t time_t +#endif +#endif + +/* + * First, a routine for setting authorization data + */ +static int xauth_namelen = 0; +static char *xauth_name = NULL; /* NULL means use default mechanism */ +static int xauth_datalen = 0; +static char *xauth_data = NULL; /* NULL means get default data */ + +/* + * This is a list of the authorization names which Xlib currently supports. + * Xau will choose the file entry which matches the earliest entry in this + * array, allowing us to prioritize these in terms of the most secure first + */ + +static char *default_xauth_names[] = { +#ifdef K5AUTH + "MIT-KERBEROS-5", +#endif +#ifdef SECURE_RPC + "SUN-DES-1", +#endif +#ifdef HASXDMAUTH + "XDM-AUTHORIZATION-1", +#endif + "MIT-MAGIC-COOKIE-1" +}; + +static int default_xauth_lengths[] = { +#ifdef K5AUTH + 14, /* strlen ("MIT-KERBEROS-5") */ +#endif +#ifdef SECURE_RPC + 9, /* strlen ("SUN-DES-1") */ +#endif +#ifdef HASXDMAUTH + 19, /* strlen ("XDM-AUTHORIZATION-1") */ +#endif + 18 /* strlen ("MIT-MAGIC-COOKIE-1") */ +}; + +#define NUM_DEFAULT_AUTH (sizeof (default_xauth_names) / sizeof (default_xauth_names[0])) + +static char **xauth_names = default_xauth_names; +static int *xauth_lengths = default_xauth_lengths; + +static int xauth_names_length = NUM_DEFAULT_AUTH; + +void XSetAuthorization (name, namelen, data, datalen) + int namelen, datalen; /* lengths of name and data */ + char *name, *data; /* NULL or arbitrary array of bytes */ +{ + char *tmpname, *tmpdata; + + _XLockMutex(_Xglobal_lock); + if (xauth_name) Xfree (xauth_name); /* free any existing data */ + if (xauth_data) Xfree (xauth_data); + + xauth_name = xauth_data = NULL; /* mark it no longer valid */ + xauth_namelen = xauth_datalen = 0; + _XUnlockMutex(_Xglobal_lock); + + if (namelen < 0) namelen = 0; /* check for bogus inputs */ + if (datalen < 0) datalen = 0; /* maybe should return? */ + + if (namelen > 0) { /* try to allocate space */ + tmpname = Xmalloc ((unsigned) namelen); + if (!tmpname) return; + memcpy (tmpname, name, namelen); + } else { + tmpname = NULL; + } + + if (datalen > 0) { + tmpdata = Xmalloc ((unsigned) datalen); + if (!tmpdata) { + if (tmpname) (void) Xfree (tmpname); + return; + } + memcpy (tmpdata, data, datalen); + } else { + tmpdata = NULL; + } + + _XLockMutex(_Xglobal_lock); + xauth_name = tmpname; /* and store the suckers */ + xauth_namelen = namelen; + if (tmpname) + { + xauth_names = &xauth_name; + xauth_lengths = &xauth_namelen; + xauth_names_length = 1; + } + else + { + xauth_names = default_xauth_names; + xauth_lengths = default_xauth_lengths; + xauth_names_length = NUM_DEFAULT_AUTH; + } + xauth_data = tmpdata; + xauth_datalen = datalen; + _XUnlockMutex(_Xglobal_lock); + return; +} + +#ifdef SECURE_RPC +/* + * Create a credential that we can send to the X server. + */ +static int +auth_ezencode(servername, window, cred_out, len) + char *servername; + int window; + char *cred_out; + int *len; +{ + AUTH *a; + XDR xdr; + + a = (AUTH *)authdes_create(servername, window, NULL, NULL); + if (a == (AUTH *)NULL) { + perror("auth_create"); + return 0; + } + xdrmem_create(&xdr, cred_out, *len, XDR_ENCODE); + if (AUTH_MARSHALL(a, &xdr) == FALSE) { + perror("auth_marshall"); + AUTH_DESTROY(a); + return 0; + } + *len = xdr_getpos(&xdr); + AUTH_DESTROY(a); + return 1; +} +#endif + +#ifdef K5AUTH +#include <com_err.h> + +extern krb5_flags krb5_kdc_default_options; + +/* + * k5_clientauth + * + * Returns non-zero if the setup prefix has been read, + * so we can tell XOpenDisplay to not bother looking for it by + * itself. + */ +static int k5_clientauth(dpy, sprefix) + Display *dpy; + xConnSetupPrefix *sprefix; +{ + krb5_error_code retval; + xReq prefix; + char *buf; + CARD16 plen, tlen; + krb5_data kbuf; + krb5_ccache cc; + krb5_creds creds; + krb5_principal cprinc, sprinc; + krb5_ap_rep_enc_part *repl; + + krb5_init_ets(); + /* + * stage 0: get encoded principal and tgt from server + */ + _XRead(dpy, (char *)&prefix, sz_xReq); + if (prefix.reqType != 2 && prefix.reqType != 3) + /* not an auth packet... so deal */ + if (prefix.reqType == 0 || prefix.reqType == 1) + { + memcpy((char *)sprefix, (char *)&prefix, sz_xReq); + _XRead(dpy, (char *)sprefix + sz_xReq, + sz_xConnSetupPrefix - sz_xReq); /* ewww... gross */ + return 1; + } + else + { + fprintf(stderr, + "Xlib: Krb5 stage 0: got illegal connection setup success code %d\n", + prefix.reqType); + return -1; + } + if (prefix.data != 0) + { + fprintf(stderr, "Xlib: got out of sequence (%d) packet in Krb5 auth\n", + prefix.data); + return -1; + } + buf = (char *)malloc((prefix.length << 2) - sz_xReq); + if (buf == NULL) /* malloc failed. Run away! */ + { + fprintf(stderr, "Xlib: malloc bombed in Krb5 auth\n"); + return -1; + } + tlen = (prefix.length << 2) - sz_xReq; + _XRead(dpy, buf, tlen); + if (prefix.reqType == 2 && tlen < 6) + { + fprintf(stderr, "Xlib: Krb5 stage 0 reply from server too short\n"); + free(buf); + return -1; + } + if (prefix.reqType == 2) + { + plen = *(CARD16 *)buf; + kbuf.data = buf + 2; + kbuf.length = (plen > tlen) ? tlen : plen; + } + else + { + kbuf.data = buf; + kbuf.length = tlen; + } + if (XauKrb5Decode(kbuf, &sprinc)) + { + free(buf); + fprintf(stderr, "Xlib: XauKrb5Decode bombed\n"); + return -1; + } + if (prefix.reqType == 3) /* do some special stuff here */ + { + char *sname, *hostname = NULL; + + sname = (char *)malloc(krb5_princ_component(sprinc, 0)->length + 1); + if (sname == NULL) + { + free(buf); + krb5_free_principal(sprinc); + fprintf(stderr, "Xlib: malloc bombed in Krb5 auth\n"); + return -1; + } + memcpy(sname, krb5_princ_component(sprinc, 0)->data, + krb5_princ_component(sprinc, 0)->length); + sname[krb5_princ_component(sprinc, 0)->length] = '\0'; + krb5_free_principal(sprinc); + if (dpy->display_name[0] != ':') /* hunt for a hostname */ + { + char *t; + + if ((hostname = (char *)malloc(strlen(dpy->display_name))) + == NULL) + { + free(buf); + free(sname); + fprintf(stderr, "Xlib: malloc bombed in Krb5 auth\n"); + return -1; + } + strcpy(hostname, dpy->display_name); + t = strchr(hostname, ':'); + if (t == NULL) + { + free(buf); + free(sname); + free(hostname); + fprintf(stderr, + "Xlib: shouldn't get here! malformed display name."); + return -1; + } + if ((t - hostname + 1 < strlen(hostname)) && t[1] == ':') + t++; + *t = '\0'; /* truncate the dpy number out */ + } + retval = krb5_sname_to_principal(hostname, sname, + KRB5_NT_SRV_HST, &sprinc); + free(sname); + if (hostname) + free(hostname); + if (retval) + { + free(buf); + fprintf(stderr, "Xlib: krb5_sname_to_principal failed: %s\n", + error_message(retval)); + return -1; + } + } + if (retval = krb5_cc_default(&cc)) + { + free(buf); + krb5_free_principal(sprinc); + fprintf(stderr, "Xlib: krb5_cc_default failed: %s\n", + error_message(retval)); + return -1; + } + if (retval = krb5_cc_get_principal(cc, &cprinc)) + { + free(buf); + krb5_free_principal(sprinc); + fprintf(stderr, "Xlib: cannot get Kerberos principal from \"%s\": %s\n", + krb5_cc_default_name(), error_message(retval)); + return -1; + } + bzero((char *)&creds, sizeof(creds)); + creds.server = sprinc; + creds.client = cprinc; + if (prefix.reqType == 2) + { + creds.second_ticket.length = tlen - plen - 2; + creds.second_ticket.data = buf + 2 + plen; + retval = krb5_get_credentials(KRB5_GC_USER_USER | + krb5_kdc_default_options, + cc, &creds); + } + else + retval = krb5_get_credentials(krb5_kdc_default_options, + cc, &creds); + if (retval) + { + free(buf); + krb5_free_cred_contents(&creds); + fprintf(stderr, "Xlib: cannot get Kerberos credentials: %s\n", + error_message(retval)); + return -1; + } + /* + * now format the ap_req to send to the server + */ + if (prefix.reqType == 2) + retval = krb5_mk_req_extended(AP_OPTS_USE_SESSION_KEY | + AP_OPTS_MUTUAL_REQUIRED, NULL, + 0, 0, NULL, cc, + &creds, NULL, &kbuf); + else + retval = krb5_mk_req_extended(AP_OPTS_MUTUAL_REQUIRED, NULL, + 0, 0, NULL, cc, &creds, NULL, + &kbuf); + free(buf); + if (retval) /* Some manner of Kerberos lossage */ + { + krb5_free_cred_contents(&creds); + fprintf(stderr, "Xlib: krb5_mk_req_extended failed: %s\n", + error_message(retval)); + return -1; + } + prefix.reqType = 1; + prefix.data = 0; + prefix.length = (kbuf.length + sz_xReq + 3) >> 2; + /* + * stage 1: send ap_req to server + */ + _XSend(dpy, (char *)&prefix, sz_xReq); + _XSend(dpy, (char *)kbuf.data, kbuf.length); + free(kbuf.data); + /* + * stage 2: get ap_rep from server to mutually authenticate + */ + _XRead(dpy, (char *)&prefix, sz_xReq); + if (prefix.reqType != 2) + if (prefix.reqType == 0 || prefix.reqType == 1) + { + memcpy((char *)sprefix, (char *)&prefix, sz_xReq); + _XRead(dpy, (char *)sprefix + sz_xReq, + sz_xConnSetupPrefix - sz_xReq); + return 1; + } + else + { + fprintf(stderr, + "Xlib: Krb5 stage 2: got illegal connection setup success code %d\n", + prefix.reqType); + return -1; + } + if (prefix.data != 2) + return -1; + kbuf.length = (prefix.length << 2) - sz_xReq; + kbuf.data = (char *)malloc(kbuf.length); + if (kbuf.data == NULL) + { + fprintf(stderr, "Xlib: malloc bombed in Krb5 auth\n"); + return -1; + } + _XRead(dpy, (char *)kbuf.data, kbuf.length); + retval = krb5_rd_rep(&kbuf, &creds.keyblock, &repl); + if (retval) + { + free(kbuf.data); + fprintf(stderr, "Xlib: krb5_rd_rep failed: %s\n", + error_message(retval)); + return -1; + } + free(kbuf.data); + /* + * stage 3: send a short ack to the server and return + */ + prefix.reqType = 3; + prefix.data = 0; + prefix.length = sz_xReq >> 2; + _XSend(dpy, (char *)&prefix, sz_xReq); + return 0; +} +#endif /* K5AUTH */ + +static void +GetAuthorization(trans_conn, family, saddr, saddrlen, idisplay, + auth_namep, auth_namelenp, auth_datap, auth_datalenp) + XtransConnInfo trans_conn; + int family; + int saddrlen; + int idisplay; + char *saddr; + char **auth_namep; /* RETURN */ + int *auth_namelenp; /* RETURN */ + char **auth_datap; /* RETURN */ + int *auth_datalenp; /* RETURN */ +{ +#ifdef SECURE_RPC + char rpc_cred[MAX_AUTH_BYTES]; +#endif +#ifdef HASXDMAUTH + char xdmcp_data[192/8]; +#endif + char *auth_name; + int auth_namelen; + char *auth_data; + int auth_datalen; + Xauth *authptr = NULL; + +/* + * Look up the authorization protocol name and data if necessary. + */ + if (xauth_name && xauth_data) { + auth_namelen = xauth_namelen; + auth_name = xauth_name; + auth_datalen = xauth_datalen; + auth_data = xauth_data; + } else { + char dpynumbuf[40]; /* big enough to hold 2^64 and more */ + (void) sprintf (dpynumbuf, "%d", idisplay); + + authptr = XauGetBestAuthByAddr ((unsigned short) family, + (unsigned short) saddrlen, + saddr, + (unsigned short) strlen (dpynumbuf), + dpynumbuf, + xauth_names_length, + xauth_names, + xauth_lengths); + if (authptr) { + auth_namelen = authptr->name_length; + auth_name = (char *)authptr->name; + auth_datalen = authptr->data_length; + auth_data = (char *)authptr->data; + } else { + auth_namelen = 0; + auth_name = NULL; + auth_datalen = 0; + auth_data = NULL; + } + } +#ifdef HASXDMAUTH + /* + * build XDM-AUTHORIZATION-1 data + */ + if (auth_namelen == 19 && !strncmp (auth_name, "XDM-AUTHORIZATION-1", 19)) + { + int i, j; + Time_t now; + int family, addrlen; + Xtransaddr *addr = NULL; + + for (j = 0; j < 8; j++) + xdmcp_data[j] = auth_data[j]; + + _X11TransGetMyAddr(trans_conn, &family, &addrlen, &addr); + + switch( family ) + { +#ifdef AF_INET + case AF_INET: + { + /* + * addr will contain a sockaddr_in with all + * of the members already in network byte order. + */ + + for(i=4; i<8; i++) /* do sin_addr */ + xdmcp_data[j++] = ((char *)addr)[i]; + for(i=2; i<4; i++) /* do sin_port */ + xdmcp_data[j++] = ((char *)addr)[i]; + break; + } +#endif /* AF_INET */ +#ifdef AF_UNIX + case AF_UNIX: + { + /* + * We don't use the sockaddr_un for this encoding. + * Instead, we create a sockaddr_in filled with + * a decreasing counter for the address, and the + * pid for the port. + */ + + static unsigned long unix_addr = 0xFFFFFFFF; + unsigned long the_addr; + unsigned short the_port; + + _XLockMutex(_Xglobal_lock); + the_addr = unix_addr--; + _XUnlockMutex(_Xglobal_lock); + the_port = getpid (); + + xdmcp_data[j++] = (the_addr >> 24) & 0xFF; + xdmcp_data[j++] = (the_addr >> 16) & 0xFF; + xdmcp_data[j++] = (the_addr >> 8) & 0xFF; + xdmcp_data[j++] = (the_addr >> 0) & 0xFF; + xdmcp_data[j++] = (the_port >> 8) & 0xFF; + xdmcp_data[j++] = (the_port >> 0) & 0xFF; + break; + } +#endif /* AF_UNIX */ +#ifdef AF_DECnet + case AF_DECnet: + /* + * What is the defined encoding for this? + */ + break; +#endif /* AF_DECnet */ + default: + /* + * Need to return some kind of errro status here. + * maybe a NULL auth?? + */ + break; + } /* switch */ + + if (addr) + free ((char *) addr); + + time (&now); + xdmcp_data[j++] = (now >> 24) & 0xFF; + xdmcp_data[j++] = (now >> 16) & 0xFF; + xdmcp_data[j++] = (now >> 8) & 0xFF; + xdmcp_data[j++] = (now >> 0) & 0xFF; + while (j < 192 / 8) + xdmcp_data[j++] = 0; + _XLockMutex(_Xglobal_lock); + /* this function might use static data, hence the lock around it */ + XdmcpWrap (xdmcp_data, auth_data + 8, + xdmcp_data, j); + _XUnlockMutex(_Xglobal_lock); + auth_data = xdmcp_data; + auth_datalen = j; + } +#endif /* HASXDMAUTH */ +#ifdef SECURE_RPC + /* + * The SUN-DES-1 authorization protocol uses the + * "secure RPC" mechanism in SunOS 4.0+. + */ + if (auth_namelen == 9 && !strncmp(auth_name, "SUN-DES-1", 9)) { + char servernetname[MAXNETNAMELEN + 1]; + + /* + * Copy over the server's netname from the authorization + * data field filled in by XauGetAuthByAddr(). + */ + if (auth_datalen > MAXNETNAMELEN) { + auth_datalen = 0; + auth_data = NULL; + } else { + memcpy(servernetname, auth_data, auth_datalen); + servernetname[auth_datalen] = '\0'; + + auth_datalen = sizeof (rpc_cred); + if (auth_ezencode(servernetname, 100, rpc_cred, + &auth_datalen)) + auth_data = rpc_cred; + else { + auth_datalen = 0; + auth_data = NULL; + } + } + } +#endif + if (saddr) free ((char *) saddr); + if ((*auth_namelenp = auth_namelen)) + { + if ((*auth_namep = Xmalloc(auth_namelen))) + memcpy(*auth_namep, auth_name, auth_namelen); + else + *auth_namelenp = 0; + } + else + *auth_namep = NULL; + if ((*auth_datalenp = auth_datalen)) + { + if ((*auth_datap = Xmalloc(auth_datalen))) + memcpy(*auth_datap, auth_data, auth_datalen); + else + *auth_datalenp = 0; + } + else + *auth_datap = NULL; + if (authptr) XauDisposeAuth (authptr); +} diff --git a/src/Context.c b/src/Context.c new file mode 100644 index 00000000..f924c258 --- /dev/null +++ b/src/Context.c @@ -0,0 +1,317 @@ +/* $Xorg: Context.c,v 1.5 2001/02/09 02:03:31 xorgcvs Exp $ */ + +/*********************************************************** +Copyright 1987, 1988, 1990 by Digital Equipment Corporation, Maynard, + + 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 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. + +******************************************************************/ + +/* + +Copyright 1987, 1988, 1990, 1994, 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 module implements a simple sparse array. + + XSaveContext(a,b,c,d) will store d in position (a,b,c) of the array. + XFindContext(a,b,c,&d) will set d to be the value in position (a,b,c). + XDeleteContext(a,b,c) will delete the entry in (a,b,c). + + a is a display id, b is a resource id, and c is a Context. d is just an + XPointer. This code will work with any range of parameters, but is geared + to be most efficient with very few (one or two) different a's. + +*/ + +#include "Xlibint.h" +#include "Xutil.h" +#ifdef XTHREADS +#include "locking.h" +#endif + +#define INITHASHMASK 63 /* Number of entries originally in the hash table. */ + +typedef struct _TableEntryRec { /* Stores one entry. */ + XID rid; + XContext context; + XPointer data; + struct _TableEntryRec *next; +} TableEntryRec, *TableEntry; + +typedef struct _XContextDB { /* Stores hash table for one display. */ + TableEntry *table; /* Pointer to array of hash entries. */ + int mask; /* Current size of hash table minus 1. */ + int numentries; /* Number of entries currently in table. */ +#ifdef XTHREADS + LockInfoRec linfo; +#endif +} DBRec, *DB; + +#ifdef MOTIFBC +static DB NullDB = (DB)0; +#endif + +/* Given an XID and a context, returns a value between 0 and HashSize-1. + Currently, this requires that HashSize be a power of 2. +*/ + +#define Hash(db,rid,context) \ + (db)->table[(((rid) << 1) + context) & (db)->mask] + +/* Resize the given db */ + +static void ResizeTable(db) + register DB db; +{ + TableEntry *otable; + register TableEntry entry, next, *pold, *head; + register int i, j; + + otable = db->table; + for (i = INITHASHMASK+1; (i + i) < db->numentries; ) + i += i; + db->table = (TableEntry *) Xcalloc((unsigned)i, sizeof(TableEntry)); + if (!db->table) { + db->table = otable; + return; + } + j = db->mask + 1; + db->mask = i - 1; + for (pold = otable ; --j >= 0; pold++) { + for (entry = *pold; entry; entry = next) { + next = entry->next; + head = &Hash(db, entry->rid, entry->context); + entry->next = *head; + *head = entry; + } + } + Xfree((char *) otable); +} + +static void _XFreeContextDB(display) + Display *display; +{ + register DB db; + register int i; + register TableEntry *pentry, entry, next; + + db = display->context_db; + if (db) { + for (i = db->mask + 1, pentry = db->table ; --i >= 0; pentry++) { + for (entry = *pentry; entry; entry = next) { + next = entry->next; + Xfree((char *)entry); + } + } + Xfree((char *) db->table); + _XFreeMutex(&db->linfo); + Xfree((char *) db); + } +} + +/* Public routines. */ + +/* Save the given value of data to correspond with the keys XID and context. + Returns nonzero error code if an error has occured, 0 otherwise. + Possible errors are Out-of-memory. +*/ + +#if NeedFunctionPrototypes +int XSaveContext( + Display *display, + register XID rid, + register XContext context, + _Xconst char* data) +#else +int XSaveContext(display, rid, context, data) + Display *display; + register XID rid; + register XContext context; + XPointer data; +#endif +{ + DB *pdb; + register DB db; + TableEntry *head; + register TableEntry entry; + +#ifdef MOTIFBC + if (!display) { + pdb = &NullDB; + db = *pdb; + } else +#endif + { + LockDisplay(display); + pdb = &display->context_db; + db = *pdb; + UnlockDisplay(display); + } + if (!db) { + db = (DB) Xmalloc(sizeof(DBRec)); + if (!db) + return XCNOMEM; + db->mask = INITHASHMASK; + db->table = (TableEntry *)Xcalloc(db->mask + 1, sizeof(TableEntry)); + if (!db->table) { + Xfree((char *)db); + return XCNOMEM; + } + db->numentries = 0; + _XCreateMutex(&db->linfo); +#ifdef MOTIFBC + if (!display) *pdb = db; else +#endif + { + LockDisplay(display); + *pdb = db; + display->free_funcs->context_db = _XFreeContextDB; + UnlockDisplay(display); + } + } + _XLockMutex(&db->linfo); + head = &Hash(db, rid, context); + _XUnlockMutex(&db->linfo); + for (entry = *head; entry; entry = entry->next) { + if (entry->rid == rid && entry->context == context) { + entry->data = (XPointer)data; + return 0; + } + } + entry = (TableEntry) Xmalloc(sizeof(TableEntryRec)); + if (!entry) + return XCNOMEM; + entry->rid = rid; + entry->context = context; + entry->data = (XPointer)data; + entry->next = *head; + *head = entry; + _XLockMutex(&db->linfo); + db->numentries++; + if (db->numentries > (db->mask << 2)) + ResizeTable(db); + _XUnlockMutex(&db->linfo); + return 0; +} + + + +/* Given an XID and context, returns the associated data. Note that data + here is a pointer since it is a return value. Returns nonzero error code + if an error has occured, 0 otherwise. Possible errors are Entry-not-found. +*/ + +int XFindContext(display, rid, context, data) + Display *display; + register XID rid; + register XContext context; + XPointer *data; /* RETURN */ +{ + register DB db; + register TableEntry entry; + +#ifdef MOTIFBC + if (!display) db = NullDB; else +#endif + { + LockDisplay(display); + db = display->context_db; + UnlockDisplay(display); + } + if (!db) + return XCNOENT; + _XLockMutex(&db->linfo); + for (entry = Hash(db, rid, context); entry; entry = entry->next) + { + if (entry->rid == rid && entry->context == context) { + *data = (XPointer)entry->data; + _XUnlockMutex(&db->linfo); + return 0; + } + } + _XUnlockMutex(&db->linfo); + return XCNOENT; +} + + + +/* Deletes the entry for the given XID and context from the datastructure. + This returns the same thing that FindContext would have returned if called + with the same arguments. +*/ + +int XDeleteContext(display, rid, context) + Display *display; + register XID rid; + register XContext context; +{ + register DB db; + register TableEntry entry, *prev; + +#ifdef MOTIFBC + if (!display) db = NullDB; else +#endif + { + LockDisplay(display); + db = display->context_db; + UnlockDisplay(display); + } + if (!db) + return XCNOENT; + _XLockMutex(&db->linfo); + for (prev = &Hash(db, rid, context); + (entry = *prev); + prev = &entry->next) { + if (entry->rid == rid && entry->context == context) { + *prev = entry->next; + Xfree((char *) entry); + db->numentries--; + if (db->numentries < db->mask && db->mask > INITHASHMASK) + ResizeTable(db); + _XUnlockMutex(&db->linfo); + return 0; + } + } + _XUnlockMutex(&db->linfo); + return XCNOENT; +} diff --git a/src/ConvSel.c b/src/ConvSel.c new file mode 100644 index 00000000..b7148a98 --- /dev/null +++ b/src/ConvSel.c @@ -0,0 +1,49 @@ +/* $Xorg: ConvSel.c,v 1.4 2001/02/09 02:03:31 xorgcvs Exp $ */ +/* + +Copyright 1986,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. + +*/ + +#include "Xlibint.h" + +XConvertSelection(dpy, selection, target, property, requestor, time) +register Display *dpy; +Atom selection, target; +Atom property; +Window requestor; +Time time; +{ + register xConvertSelectionReq *req; + + LockDisplay(dpy); + GetReq(ConvertSelection, req); + req->selection = selection; + req->target = target; + req->property = property; + req->requestor = requestor; + req->time = time; + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} diff --git a/src/CopyArea.c b/src/CopyArea.c new file mode 100644 index 00000000..5a4c42ba --- /dev/null +++ b/src/CopyArea.c @@ -0,0 +1,59 @@ +/* $Xorg: CopyArea.c,v 1.4 2001/02/09 02:03:32 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XCopyArea(dpy, src_drawable, dst_drawable, gc, + src_x, src_y, width, height, + dst_x, dst_y) + register Display *dpy; + Drawable src_drawable, dst_drawable; + GC gc; + int src_x, src_y; + unsigned int width, height; + int dst_x, dst_y; + +{ + register xCopyAreaReq *req; + + LockDisplay(dpy); + FlushGC(dpy, gc); + GetReq(CopyArea, req); + req->srcDrawable = src_drawable; + req->dstDrawable = dst_drawable; + req->gc = gc->gid; + req->srcX = src_x; + req->srcY = src_y; + req->dstX = dst_x; + req->dstY = dst_y; + req->width = width; + req->height = height; + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} + diff --git a/src/CopyCmap.c b/src/CopyCmap.c new file mode 100644 index 00000000..a6873765 --- /dev/null +++ b/src/CopyCmap.c @@ -0,0 +1,49 @@ +/* $Xorg: CopyCmap.c,v 1.4 2001/02/09 02:03:32 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +Colormap XCopyColormapAndFree(dpy, src_cmap) +register Display *dpy; +Colormap src_cmap; +{ + Colormap mid; + register xCopyColormapAndFreeReq *req; + + LockDisplay(dpy); + GetReq(CopyColormapAndFree, req); + + mid = req->mid = XAllocID(dpy); + req->srcCmap = src_cmap; + + UnlockDisplay(dpy); + SyncHandle(); + + _XcmsCopyCmapRecAndFree(dpy, src_cmap, mid); + + return(mid); +} diff --git a/src/CopyGC.c b/src/CopyGC.c new file mode 100644 index 00000000..ec228794 --- /dev/null +++ b/src/CopyGC.c @@ -0,0 +1,134 @@ +/* $Xorg: CopyGC.c,v 1.4 2001/02/09 02:03:32 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XCopyGC (dpy, srcGC, mask, destGC) + register Display *dpy; + unsigned long mask; /* which ones to set initially */ + GC srcGC, destGC; +{ + register XGCValues *destgv = &destGC->values, + *srcgv = &srcGC->values; + register xCopyGCReq *req; + register _XExtension *ext; + + LockDisplay(dpy); + + mask &= (1L << (GCLastBit + 1)) - 1; + /* if some of the source values to be copied are "dirty", flush them + out before sending the CopyGC request. */ + if (srcGC->dirty & mask) + _XFlushGCCache(dpy, srcGC); + + /* mark the copied values "not dirty" in the destination. */ + destGC->dirty &= ~mask; + + GetReq(CopyGC, req); + req->srcGC = srcGC->gid; + req->dstGC = destGC->gid; + req->mask = mask; + + if (mask & GCFunction) + destgv->function = srcgv->function; + + if (mask & GCPlaneMask) + destgv->plane_mask = srcgv->plane_mask; + + if (mask & GCForeground) + destgv->foreground = srcgv->foreground; + + if (mask & GCBackground) + destgv->background = srcgv->background; + + if (mask & GCLineWidth) + destgv->line_width = srcgv->line_width; + + if (mask & GCLineStyle) + destgv->line_style = srcgv->line_style; + + if (mask & GCCapStyle) + destgv->cap_style = srcgv->cap_style; + + if (mask & GCJoinStyle) + destgv->join_style = srcgv->join_style; + + if (mask & GCFillStyle) + destgv->fill_style = srcgv->fill_style; + + if (mask & GCFillRule) + destgv->fill_rule = srcgv->fill_rule; + + if (mask & GCArcMode) + destgv->arc_mode = srcgv->arc_mode; + + if (mask & GCTile) + destgv->tile = srcgv->tile; + + if (mask & GCStipple) + destgv->stipple = srcgv->stipple; + + if (mask & GCTileStipXOrigin) + destgv->ts_x_origin = srcgv->ts_x_origin; + + if (mask & GCTileStipYOrigin) + destgv->ts_y_origin = srcgv->ts_y_origin; + + if (mask & GCFont) + destgv->font = srcgv->font; + + if (mask & GCSubwindowMode) + destgv->subwindow_mode = srcgv->subwindow_mode; + + if (mask & GCGraphicsExposures) + destgv->graphics_exposures = srcgv->graphics_exposures; + + if (mask & GCClipXOrigin) + destgv->clip_x_origin = srcgv->clip_x_origin; + + if (mask & GCClipYOrigin) + destgv->clip_y_origin = srcgv->clip_y_origin; + + if (mask & GCClipMask) { + destGC->rects = srcGC->rects; + destgv->clip_mask = srcgv->clip_mask; + } + + if (mask & GCDashOffset) + destgv->dash_offset = srcgv->dash_offset; + + if (mask & GCDashList) { + destGC->dashes = srcGC->dashes; + destgv->dashes = srcgv->dashes; + } + /* call out to any extensions interested */ + for (ext = dpy->ext_procs; ext; ext = ext->next) + if (ext->copy_GC) (*ext->copy_GC)(dpy, destGC, &ext->codes); + UnlockDisplay(dpy); + SyncHandle(); + return 1; + } diff --git a/src/CopyPlane.c b/src/CopyPlane.c new file mode 100644 index 00000000..1df2b14a --- /dev/null +++ b/src/CopyPlane.c @@ -0,0 +1,61 @@ +/* $Xorg: CopyPlane.c,v 1.4 2001/02/09 02:03:32 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XCopyPlane(dpy, src_drawable, dst_drawable, gc, + src_x, src_y, width, height, + dst_x, dst_y, bit_plane) + register Display *dpy; + Drawable src_drawable, dst_drawable; + GC gc; + int src_x, src_y; + unsigned int width, height; + int dst_x, dst_y; + unsigned long bit_plane; + +{ + register xCopyPlaneReq *req; + + LockDisplay(dpy); + FlushGC(dpy, gc); + GetReq(CopyPlane, req); + req->srcDrawable = src_drawable; + req->dstDrawable = dst_drawable; + req->gc = gc->gid; + req->srcX = src_x; + req->srcY = src_y; + req->dstX = dst_x; + req->dstY = dst_y; + req->width = width; + req->height = height; + req->bitPlane = bit_plane; + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} + diff --git a/src/CrBFData.c b/src/CrBFData.c new file mode 100644 index 00000000..70060a96 --- /dev/null +++ b/src/CrBFData.c @@ -0,0 +1,85 @@ +/* $Xorg: CrBFData.c,v 1.4 2001/02/09 02:03:32 xorgcvs Exp $ */ +/* + +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. + +*/ + +#include "Xlib.h" + +/* + * XCreateBitmapFromData: Routine to make a pixmap of depth 1 from user + * supplied data. + * D is any drawable on the same screen that the pixmap will be used in. + * Data is a pointer to the bit data, and + * width & height give the size in bits of the pixmap. + * + * The following format is assumed for data: + * + * format=XYPixmap + * bit_order=LSBFirst + * byte_order=LSBFirst + * padding=8 + * bitmap_unit=8 + * xoffset=0 + * no extra bytes per line + */ +#if NeedFunctionPrototypes +Pixmap XCreateBitmapFromData( + Display *display, + Drawable d, + _Xconst char *data, + unsigned int width, + unsigned int height) +#else +Pixmap XCreateBitmapFromData(display, d, data, width, height) + Display *display; + Drawable d; + char *data; + unsigned int width, height; +#endif +{ + XImage ximage; + GC gc; + Pixmap pix; + + pix = XCreatePixmap(display, d, width, height, 1); + if (! (gc = XCreateGC(display, pix, (unsigned long) 0, (XGCValues *) 0))) + return (Pixmap) None; + ximage.height = height; + ximage.width = width; + ximage.depth = 1; + ximage.bits_per_pixel = 1; + ximage.xoffset = 0; + ximage.format = XYPixmap; + ximage.data = (char *)data; + ximage.byte_order = LSBFirst; + ximage.bitmap_unit = 8; + ximage.bitmap_bit_order = LSBFirst; + ximage.bitmap_pad = 8; + ximage.bytes_per_line = (width+7)/8; + + XPutImage(display, pix, gc, &ximage, 0, 0, 0, 0, width, height); + XFreeGC(display, gc); + return(pix); +} diff --git a/src/CrCmap.c b/src/CrCmap.c new file mode 100644 index 00000000..3c1878df --- /dev/null +++ b/src/CrCmap.c @@ -0,0 +1,53 @@ +/* $Xorg: CrCmap.c,v 1.4 2001/02/09 02:03:32 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +Colormap XCreateColormap(dpy, w, visual, alloc) +register Display *dpy; +Window w; +Visual *visual; +int alloc; +{ + register xCreateColormapReq *req; + Colormap mid; + + LockDisplay(dpy); + GetReq(CreateColormap, req); + req->window = w; + mid = req->mid = XAllocID(dpy); + req->alloc = alloc; + if (visual == CopyFromParent) req->visual = CopyFromParent; + else req->visual = visual->visualid; + + UnlockDisplay(dpy); + SyncHandle(); + + _XcmsAddCmapRec(dpy, mid, w, visual); + + return(mid); +} diff --git a/src/CrCursor.c b/src/CrCursor.c new file mode 100644 index 00000000..93c7a006 --- /dev/null +++ b/src/CrCursor.c @@ -0,0 +1,57 @@ +/* $Xorg: CrCursor.c,v 1.4 2001/02/09 02:03:32 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +Cursor XCreatePixmapCursor(dpy, source, mask, foreground, background, x, y) + register Display *dpy; + Pixmap source, mask; + XColor *foreground, *background; + unsigned int x, y; + +{ + register xCreateCursorReq *req; + Cursor cid; + + LockDisplay(dpy); + GetReq(CreateCursor, req); + req->cid = cid = XAllocID(dpy); + req->source = source; + req->mask = mask; + req->foreRed = foreground->red; + req->foreGreen = foreground->green; + req->foreBlue = foreground->blue; + req->backRed = background->red; + req->backGreen = background->green; + req->backBlue = background->blue; + req->x = x; + req->y = y; + UnlockDisplay(dpy); + SyncHandle(); + return (cid); +} + diff --git a/src/CrGC.c b/src/CrGC.c new file mode 100644 index 00000000..969f6d88 --- /dev/null +++ b/src/CrGC.c @@ -0,0 +1,342 @@ +/* $Xorg: CrGC.c,v 1.5 2001/02/09 02:03:32 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +#ifdef __STDC__ +#define Const const +#else +#define Const /**/ +#endif + +static XGCValues Const initial_GC = { + GXcopy, /* function */ + AllPlanes, /* plane_mask */ + 0L, /* foreground */ + 1L, /* background */ + 0, /* line_width */ + LineSolid, /* line_style */ + CapButt, /* cap_style */ + JoinMiter, /* join_style */ + FillSolid, /* fill_style */ + EvenOddRule,/* fill_rule */ + ArcPieSlice,/* arc_mode */ + (Pixmap)~0L,/* tile, impossible (unknown) resource */ + (Pixmap)~0L,/* stipple, impossible (unknown) resource */ + 0, /* ts_x_origin */ + 0, /* ts_y_origin */ + (Font)~0L, /* font, impossible (unknown) resource */ + ClipByChildren, /* subwindow_mode */ + True, /* graphics_exposures */ + 0, /* clip_x_origin */ + 0, /* clip_y_origin */ + None, /* clip_mask */ + 0, /* dash_offset */ + 4 /* dashes (list [4,4]) */ +}; + +static void _XGenerateGCList(); + +GC XCreateGC (dpy, d, valuemask, values) + register Display *dpy; + Drawable d; /* Window or Pixmap for which depth matches */ + unsigned long valuemask; /* which ones to set initially */ + XGCValues *values; /* the values themselves */ +{ + register GC gc; + register xCreateGCReq *req; + register _XExtension *ext; + + LockDisplay(dpy); + if ((gc = (GC)Xmalloc (sizeof(struct _XGC))) == NULL) { + UnlockDisplay(dpy); + SyncHandle(); + return (NULL); + } + gc->rects = 0; + gc->dashes = 0; + gc->ext_data = NULL; + gc->values = initial_GC; + gc->dirty = 0L; + + valuemask &= (1L << (GCLastBit + 1)) - 1; + if (valuemask) _XUpdateGCCache (gc, valuemask, values); + + GetReq(CreateGC, req); + req->drawable = d; + req->gc = gc->gid = XAllocID(dpy); + + if ((req->mask = gc->dirty)) + _XGenerateGCList (dpy, gc, (xReq *) req); + /* call out to any extensions interested */ + for (ext = dpy->ext_procs; ext; ext = ext->next) + if (ext->create_GC) (*ext->create_GC)(dpy, gc, &ext->codes); + gc->dirty = 0L; /* allow extensions to see dirty bits */ + UnlockDisplay(dpy); + SyncHandle(); + return (gc); + } + +/* + * GenerateGCList looks at the GC dirty bits, and appends all the required + * long words to the request being generated. + */ + +static void +_XGenerateGCList (dpy, gc, req) + register Display *dpy; + xReq *req; + GC gc; + { + unsigned long values[32]; + register unsigned long *value = values; + long nvalues; + register XGCValues *gv = &gc->values; + register unsigned long dirty = gc->dirty; + + /* + * Note: The order of these tests are critical; the order must be the + * same as the GC mask bits in the word. + */ + if (dirty & GCFunction) *value++ = gv->function; + if (dirty & GCPlaneMask) *value++ = gv->plane_mask; + if (dirty & GCForeground) *value++ = gv->foreground; + if (dirty & GCBackground) *value++ = gv->background; + if (dirty & GCLineWidth) *value++ = gv->line_width; + if (dirty & GCLineStyle) *value++ = gv->line_style; + if (dirty & GCCapStyle) *value++ = gv->cap_style; + if (dirty & GCJoinStyle) *value++ = gv->join_style; + if (dirty & GCFillStyle) *value++ = gv->fill_style; + if (dirty & GCFillRule) *value++ = gv->fill_rule; + if (dirty & GCTile) *value++ = gv->tile; + if (dirty & GCStipple) *value++ = gv->stipple; + if (dirty & GCTileStipXOrigin) *value++ = gv->ts_x_origin; + if (dirty & GCTileStipYOrigin) *value++ = gv->ts_y_origin; + if (dirty & GCFont) *value++ = gv->font; + if (dirty & GCSubwindowMode) *value++ = gv->subwindow_mode; + if (dirty & GCGraphicsExposures) *value++ = gv->graphics_exposures; + if (dirty & GCClipXOrigin) *value++ = gv->clip_x_origin; + if (dirty & GCClipYOrigin) *value++ = gv->clip_y_origin; + if (dirty & GCClipMask) *value++ = gv->clip_mask; + if (dirty & GCDashOffset) *value++ = gv->dash_offset; + if (dirty & GCDashList) *value++ = gv->dashes; + if (dirty & GCArcMode) *value++ = gv->arc_mode; + + req->length += (nvalues = value - values); + + /* + * note: Data is a macro that uses its arguments multiple + * times, so "nvalues" is changed in a separate assignment + * statement + */ + + nvalues <<= 2; + Data32 (dpy, (long *) values, nvalues); + + } + + +_XUpdateGCCache (gc, mask, attr) + register unsigned long mask; + register XGCValues *attr; + register GC gc; + { + register XGCValues *gv = &gc->values; + + if (mask & GCFunction) + if (gv->function != attr->function) { + gv->function = attr->function; + gc->dirty |= GCFunction; + } + + if (mask & GCPlaneMask) + if (gv->plane_mask != attr->plane_mask) { + gv->plane_mask = attr->plane_mask; + gc->dirty |= GCPlaneMask; + } + + if (mask & GCForeground) + if (gv->foreground != attr->foreground) { + gv->foreground = attr->foreground; + gc->dirty |= GCForeground; + } + + if (mask & GCBackground) + if (gv->background != attr->background) { + gv->background = attr->background; + gc->dirty |= GCBackground; + } + + if (mask & GCLineWidth) + if (gv->line_width != attr->line_width) { + gv->line_width = attr->line_width; + gc->dirty |= GCLineWidth; + } + + if (mask & GCLineStyle) + if (gv->line_style != attr->line_style) { + gv->line_style = attr->line_style; + gc->dirty |= GCLineStyle; + } + + if (mask & GCCapStyle) + if (gv->cap_style != attr->cap_style) { + gv->cap_style = attr->cap_style; + gc->dirty |= GCCapStyle; + } + + if (mask & GCJoinStyle) + if (gv->join_style != attr->join_style) { + gv->join_style = attr->join_style; + gc->dirty |= GCJoinStyle; + } + + if (mask & GCFillStyle) + if (gv->fill_style != attr->fill_style) { + gv->fill_style = attr->fill_style; + gc->dirty |= GCFillStyle; + } + + if (mask & GCFillRule) + if (gv->fill_rule != attr->fill_rule) { + gv->fill_rule = attr->fill_rule; + gc->dirty |= GCFillRule; + } + + if (mask & GCArcMode) + if (gv->arc_mode != attr->arc_mode) { + gv->arc_mode = attr->arc_mode; + gc->dirty |= GCArcMode; + } + + /* always write through tile change, since client may have changed pixmap contents */ + if (mask & GCTile) { + gv->tile = attr->tile; + gc->dirty |= GCTile; + } + + /* always write through stipple change, since client may have changed pixmap contents */ + if (mask & GCStipple) { + gv->stipple = attr->stipple; + gc->dirty |= GCStipple; + } + + if (mask & GCTileStipXOrigin) + if (gv->ts_x_origin != attr->ts_x_origin) { + gv->ts_x_origin = attr->ts_x_origin; + gc->dirty |= GCTileStipXOrigin; + } + + if (mask & GCTileStipYOrigin) + if (gv->ts_y_origin != attr->ts_y_origin) { + gv->ts_y_origin = attr->ts_y_origin; + gc->dirty |= GCTileStipYOrigin; + } + + if (mask & GCFont) + if (gv->font != attr->font) { + gv->font = attr->font; + gc->dirty |= GCFont; + } + + if (mask & GCSubwindowMode) + if (gv->subwindow_mode != attr->subwindow_mode) { + gv->subwindow_mode = attr->subwindow_mode; + gc->dirty |= GCSubwindowMode; + } + + if (mask & GCGraphicsExposures) + if (gv->graphics_exposures != attr->graphics_exposures) { + gv->graphics_exposures = attr->graphics_exposures; + gc->dirty |= GCGraphicsExposures; + } + + if (mask & GCClipXOrigin) + if (gv->clip_x_origin != attr->clip_x_origin) { + gv->clip_x_origin = attr->clip_x_origin; + gc->dirty |= GCClipXOrigin; + } + + if (mask & GCClipYOrigin) + if (gv->clip_y_origin != attr->clip_y_origin) { + gv->clip_y_origin = attr->clip_y_origin; + gc->dirty |= GCClipYOrigin; + } + + /* always write through mask change, since client may have changed pixmap contents */ + if (mask & GCClipMask) { + gv->clip_mask = attr->clip_mask; + gc->dirty |= GCClipMask; + gc->rects = 0; + } + + if (mask & GCDashOffset) + if (gv->dash_offset != attr->dash_offset) { + gv->dash_offset = attr->dash_offset; + gc->dirty |= GCDashOffset; + } + + if (mask & GCDashList) + if ((gv->dashes != attr->dashes) || (gc->dashes == True)) { + gv->dashes = attr->dashes; + gc->dirty |= GCDashList; + gc->dashes = 0; + } + return 0; + } + +/* can only call when display is already locked. */ + +void _XFlushGCCache(dpy, gc) + Display *dpy; + GC gc; +{ + register xChangeGCReq *req; + register _XExtension *ext; + + if (gc->dirty) { + GetReq(ChangeGC, req); + req->gc = gc->gid; + req->mask = gc->dirty; + _XGenerateGCList (dpy, gc, (xReq *) req); + /* call out to any extensions interested */ + for (ext = dpy->ext_procs; ext; ext = ext->next) + if (ext->flush_GC) (*ext->flush_GC)(dpy, gc, &ext->codes); + gc->dirty = 0L; /* allow extensions to see dirty bits */ + } +} + +void XFlushGC(dpy, gc) + Display *dpy; + GC gc; +{ + FlushGC(dpy, gc); +} + +GContext XGContextFromGC(gc) + GC gc; + { return (gc->gid); } diff --git a/src/CrGlCur.c b/src/CrGlCur.c new file mode 100644 index 00000000..d6fc4039 --- /dev/null +++ b/src/CrGlCur.c @@ -0,0 +1,59 @@ +/* $Xorg: CrGlCur.c,v 1.4 2001/02/09 02:03:32 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +Cursor XCreateGlyphCursor(dpy, source_font, mask_font, + source_char, mask_char, + foreground, background) + register Display *dpy; + Font source_font, mask_font; + unsigned int source_char, mask_char; + XColor *foreground, *background; + +{ + Cursor cid; + register xCreateGlyphCursorReq *req; + + LockDisplay(dpy); + GetReq(CreateGlyphCursor, req); + cid = req->cid = XAllocID(dpy); + req->source = source_font; + req->mask = mask_font; + req->sourceChar = source_char; + req->maskChar = mask_char; + req->foreRed = foreground->red; + req->foreGreen = foreground->green; + req->foreBlue = foreground->blue; + req->backRed = background->red; + req->backGreen = background->green; + req->backBlue = background->blue; + UnlockDisplay(dpy); + SyncHandle(); + return (cid); +} + diff --git a/src/CrPFBData.c b/src/CrPFBData.c new file mode 100644 index 00000000..f28aabbb --- /dev/null +++ b/src/CrPFBData.c @@ -0,0 +1,83 @@ +/* $Xorg: CrPFBData.c,v 1.4 2001/02/09 02:03:32 xorgcvs Exp $ */ +/* + +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. + +*/ + +#include "Xlib.h" +#include <stdio.h> + +/* + * XCreatePixmapFromBitmapData: Routine to make a pixmap from user supplied bitmap data. + * D is any drawable on the same screen that the pixmap will be used in. + * Data is a pointer to the bit data, and + * width & height give the size in bits of the pixmap. + * Fg and Bg are the pixel values to use for the two colors. + * Depth is the depth of the pixmap to create. + * + * The following format is assumed for data: + * + * format=XYPixmap + * bit_order=LSBFirst + * byte_order=LSBFirst + * padding=8 + * bitmap_unit=8 + * xoffset=0 + * no extra bytes per line + */ +Pixmap XCreatePixmapFromBitmapData(display,d,data,width,height,fg,bg,depth) + Display *display; + Drawable d; + char *data; + unsigned int width, height; + unsigned long fg, bg; + unsigned int depth; +{ + XImage ximage; + GC gc; + XGCValues gcv; + Pixmap pix; + + pix = XCreatePixmap(display, d, width, height, depth); + gcv.foreground = fg; + gcv.background = bg; + if (! (gc = XCreateGC(display, pix, GCForeground|GCBackground, &gcv))) + return (Pixmap) NULL; + ximage.height = height; + ximage.width = width; + ximage.depth = 1; + ximage.bits_per_pixel = 1; + ximage.xoffset = 0; + ximage.format = XYBitmap; + ximage.data = data; + ximage.byte_order = LSBFirst; + ximage.bitmap_unit = 8; + ximage.bitmap_bit_order = LSBFirst; + ximage.bitmap_pad = 8; + ximage.bytes_per_line = (width+7)/8; + + XPutImage(display, pix, gc, &ximage, 0, 0, 0, 0, width, height); + XFreeGC(display, gc); + return(pix); +} diff --git a/src/CrPixmap.c b/src/CrPixmap.c new file mode 100644 index 00000000..2505f48a --- /dev/null +++ b/src/CrPixmap.c @@ -0,0 +1,49 @@ +/* $Xorg: CrPixmap.c,v 1.4 2001/02/09 02:03:32 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +Pixmap XCreatePixmap (dpy, d, width, height, depth) + register Display *dpy; + Drawable d; + unsigned int width, height, depth; +{ + Pixmap pid; + register xCreatePixmapReq *req; + + LockDisplay(dpy); + GetReq(CreatePixmap, req); + req->drawable = d; + req->width = width; + req->height = height; + req->depth = depth; + pid = req->pid = XAllocID(dpy); + UnlockDisplay(dpy); + SyncHandle(); + return (pid); +} + diff --git a/src/CrWindow.c b/src/CrWindow.c new file mode 100644 index 00000000..418f9867 --- /dev/null +++ b/src/CrWindow.c @@ -0,0 +1,74 @@ +/* $Xorg: CrWindow.c,v 1.4 2001/02/09 02:03:32 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +Window XCreateSimpleWindow(dpy, parent, x, y, width, height, + borderWidth, border, background) + register Display *dpy; + Window parent; + int x, y; + unsigned int width, height, borderWidth; + unsigned long border; + unsigned long background; +{ + Window wid; + register xCreateWindowReq *req; + + LockDisplay(dpy); + GetReqExtra(CreateWindow, 8, req); + req->parent = parent; + req->x = x; + req->y = y; + req->width = width; + req->height = height; + req->borderWidth = borderWidth; + req->depth = 0; + req->class = CopyFromParent; + req->visual = CopyFromParent; + wid = req->wid = XAllocID(dpy); + req->mask = CWBackPixel | CWBorderPixel; + +#ifdef MUSTCOPY + { + unsigned long lbackground = background, lborder = border; + dpy->bufptr -= 8; + Data32 (dpy, (long *) &lbackground, 4); + Data32 (dpy, (long *) &lborder, 4); + } +#else + { + register CARD32 *valuePtr = (CARD32 *) NEXTPTR(req,xCreateWindowReq); + *valuePtr++ = background; + *valuePtr = border; + } +#endif /* MUSTCOPY */ + + UnlockDisplay(dpy); + SyncHandle(); + return (wid); + } diff --git a/src/Cursor.c b/src/Cursor.c new file mode 100644 index 00000000..55ff456c --- /dev/null +++ b/src/Cursor.c @@ -0,0 +1,51 @@ +/* $Xorg: Cursor.c,v 1.4 2001/02/09 02:03:32 xorgcvs Exp $ */ +/* + +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. + +*/ + +#include "Xlibint.h" +static XColor foreground = { 0, 0, 0, 0 }; /* black */ +static XColor background = { 0, 65535, 65535, 65535 }; /* white */ + +Cursor XCreateFontCursor(dpy, which) + Display *dpy; + unsigned int which; +{ + /* + * the cursor font contains the shape glyph followed by the mask + * glyph; so character position 0 contains a shape, 1 the mask for 0, + * 2 a shape, etc. <X11/cursorfont.h> contains hash define names + * for all of these. + */ + + if (dpy->cursor_font == None) { + dpy->cursor_font = XLoadFont (dpy, CURSORFONT); + if (dpy->cursor_font == None) return None; + } + + return XCreateGlyphCursor (dpy, dpy->cursor_font, dpy->cursor_font, + which, which + 1, &foreground, &background); +} + diff --git a/src/DefCursor.c b/src/DefCursor.c new file mode 100644 index 00000000..d4eadea2 --- /dev/null +++ b/src/DefCursor.c @@ -0,0 +1,46 @@ +/* $Xorg: DefCursor.c,v 1.4 2001/02/09 02:03:32 xorgcvs Exp $ */ +/* + +Copyright 1986,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. + +*/ + +#include "Xlibint.h" + +XDefineCursor (dpy, w, cursor) + register Display *dpy; + Window w; + Cursor cursor; +{ + register xChangeWindowAttributesReq *req; + + LockDisplay(dpy); + GetReqExtra (ChangeWindowAttributes, 4, req); + req->window = w; + req->valueMask = CWCursor; + OneDataCard32 (dpy, NEXTPTR(req,xChangeWindowAttributesReq), cursor); + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} + diff --git a/src/DelProp.c b/src/DelProp.c new file mode 100644 index 00000000..11bf3a3d --- /dev/null +++ b/src/DelProp.c @@ -0,0 +1,44 @@ +/* $Xorg: DelProp.c,v 1.4 2001/02/09 02:03:32 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XDeleteProperty(dpy, window, property) +register Display *dpy; +Window window; +Atom property; +{ + register xDeletePropertyReq *req; + + LockDisplay(dpy); + GetReq(DeleteProperty, req); + req->window = window; + req->property = property; + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} diff --git a/src/Depths.c b/src/Depths.c new file mode 100644 index 00000000..34756e71 --- /dev/null +++ b/src/Depths.c @@ -0,0 +1,60 @@ +/* $Xorg: Depths.c,v 1.4 2001/02/09 02:03:32 xorgcvs Exp $ */ +/* + +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. + +*/ + +#include "Xlibint.h" +#include <stdio.h> + +/* + * XListDepths - return info from connection setup + */ +int *XListDepths (dpy, scrnum, countp) + Display *dpy; + int scrnum; + int *countp; +{ + Screen *scr; + int count; + int *depths; + + if (scrnum < 0 || scrnum >= dpy->nscreens) return NULL; + + scr = &dpy->screens[scrnum]; + if ((count = scr->ndepths) > 0) { + register Depth *dp; + register int i; + + depths = (int *) Xmalloc (count * sizeof(int)); + if (!depths) return NULL; + for (i = 0, dp = scr->depths; i < count; i++, dp++) + depths[i] = dp->depth; + } else { + /* a screen must have a depth */ + return NULL; + } + *countp = count; + return depths; +} diff --git a/src/DestSubs.c b/src/DestSubs.c new file mode 100644 index 00000000..98aadd6b --- /dev/null +++ b/src/DestSubs.c @@ -0,0 +1,42 @@ +/* $Xorg: DestSubs.c,v 1.4 2001/02/09 02:03:32 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XDestroySubwindows(dpy, win) +register Display *dpy; +Window win; +{ + register xResourceReq *req; + + LockDisplay(dpy); + GetResReq (DestroySubwindows,win, req); + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} + diff --git a/src/DestWind.c b/src/DestWind.c new file mode 100644 index 00000000..319e4ec3 --- /dev/null +++ b/src/DestWind.c @@ -0,0 +1,42 @@ +/* $Xorg: DestWind.c,v 1.4 2001/02/09 02:03:32 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XDestroyWindow (dpy, w) + register Display *dpy; + Window w; +{ + register xResourceReq *req; + + LockDisplay(dpy); + GetResReq(DestroyWindow, w, req); + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} + diff --git a/src/DisName.c b/src/DisName.c new file mode 100644 index 00000000..17ebf356 --- /dev/null +++ b/src/DisName.c @@ -0,0 +1,62 @@ +/* $Xorg: DisName.c,v 1.4 2001/02/09 02:03:32 xorgcvs Exp $ */ + +/* + +Copyright 1994, 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. + +*/ + +/* XDisplayName.c */ +/* + * Returns the name of the display XOpenDisplay would use. This is better + * than just printing the "display" variable in a program because that + * could be NULL and/or there could be an environment variable set. + * This makes it easier for programmers to provide meaningful error + * messages. + * + * + * For example, this is used in XOpenDisplay() as + * strncpy( displaybuf, XDisplayName( display ), sizeof(displaybuf) ); + * if ( *displaybuf == '\0' ) return( NULL ); + * This check is actually unnecessary because the next thing is an index() + * call looking for a ':' which will fail and we'll return(NULL). + */ +/* Written at Waterloo - JMSellens */ + +#include <stdio.h> + +extern char *getenv(); + +char * +XDisplayName( display ) + char *display; +{ + char *d; + if ( display != (char *)NULL && *display != '\0' ) + return( display ); + if ( (d = getenv( "DISPLAY" )) != (char *)NULL ) + return( d ); + return( "" ); +} diff --git a/src/DrArc.c b/src/DrArc.c new file mode 100644 index 00000000..466e7e15 --- /dev/null +++ b/src/DrArc.c @@ -0,0 +1,79 @@ +/* $Xorg: DrArc.c,v 1.4 2001/02/09 02:03:32 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +/* Note to future maintainers: XDrawArc does NOT batch successive PolyArc + requests into a single request like XDrawLine, XDrawPoint, etc. + We don't do this because X_PolyArc applies the GC's join-style if + the last point in one arc coincides with the first point in another. + The client wouldn't expect this and would have no easy way to defeat it. */ + +#include "Xlibint.h" + +XDrawArc(dpy, d, gc, x, y, width, height, angle1, angle2) + register Display *dpy; + Drawable d; + GC gc; + int x, y; /* INT16 */ + unsigned int width, height; /* CARD16 */ + int angle1, angle2; /* INT16 */ +{ + register xPolyArcReq *req; + register xArc *arc; +#ifdef MUSTCOPY + xArc arcdata; + long len = SIZEOF(xArc); + + arc = &arcdata; +#endif /* MUSTCOPY */ + + LockDisplay(dpy); + FlushGC(dpy, gc); + GetReqExtra (PolyArc, SIZEOF(xArc), req); + + req->drawable = d; + req->gc = gc->gid; + +#ifndef MUSTCOPY + arc = (xArc *) NEXTPTR(req,xPolyArcReq); +#endif /* MUSTCOPY */ + + arc->x = x; + arc->y = y; + arc->width = width; + arc->height = height; + arc->angle1 = angle1; + arc->angle2 = angle2; + +#ifdef MUSTCOPY + dpy->bufptr -= SIZEOF(xArc); + Data (dpy, (char *) arc, len); +#endif /* MUSTCOPY */ + + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} diff --git a/src/DrArcs.c b/src/DrArcs.c new file mode 100644 index 00000000..9f8ef96a --- /dev/null +++ b/src/DrArcs.c @@ -0,0 +1,54 @@ +/* $Xorg: DrArcs.c,v 1.4 2001/02/09 02:03:32 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +#define arc_scale (SIZEOF(xArc) / 4) + +XDrawArcs(dpy, d, gc, arcs, n_arcs) +register Display *dpy; +Drawable d; +GC gc; +XArc *arcs; +int n_arcs; +{ + register xPolyArcReq *req; + register long len; + + LockDisplay(dpy); + FlushGC(dpy, gc); + GetReq(PolyArc,req); + req->drawable = d; + req->gc = gc->gid; + len = ((long)n_arcs) * arc_scale; + SetReqLen(req, len, 1); + len <<= 2; /* watch out for macros... */ + Data16 (dpy, (short *) arcs, len); + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} diff --git a/src/DrLine.c b/src/DrLine.c new file mode 100644 index 00000000..6b17fbe5 --- /dev/null +++ b/src/DrLine.c @@ -0,0 +1,95 @@ +/* $Xorg: DrLine.c,v 1.4 2001/02/09 02:03:32 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +/* precompute the maximum size of batching request allowed */ + +#define wsize (SIZEOF(xPolySegmentReq) + WLNSPERBATCH * SIZEOF(xSegment)) +#define zsize (SIZEOF(xPolySegmentReq) + ZLNSPERBATCH * SIZEOF(xSegment)) + +XDrawLine (dpy, d, gc, x1, y1, x2, y2) + register Display *dpy; + Drawable d; + GC gc; + int x1, y1, x2, y2; +{ + register xSegment *segment; +#ifdef MUSTCOPY + xSegment segmentdata; + long len = SIZEOF(xSegment); + + segment = &segmentdata; +#endif /* not MUSTCOPY */ + + LockDisplay(dpy); + FlushGC(dpy, gc); + + { + register xPolySegmentReq *req = (xPolySegmentReq *) dpy->last_req; + + /* if same as previous request, with same drawable, batch requests */ + if ( + (req->reqType == X_PolySegment) + && (req->drawable == d) + && (req->gc == gc->gid) + && ((dpy->bufptr + SIZEOF(xSegment)) <= dpy->bufmax) + && (((char *)dpy->bufptr - (char *)req) < (gc->values.line_width ? + wsize : zsize)) ) { + req->length += SIZEOF(xSegment) >> 2; +#ifndef MUSTCOPY + segment = (xSegment *) dpy->bufptr; + dpy->bufptr += SIZEOF(xSegment); +#endif /* not MUSTCOPY */ + } + + else { + GetReqExtra (PolySegment, SIZEOF(xSegment), req); + req->drawable = d; + req->gc = gc->gid; +#ifdef MUSTCOPY + dpy->bufptr -= SIZEOF(xSegment); +#else + segment = (xSegment *) NEXTPTR(req,xPolySegmentReq); +#endif /* MUSTCOPY */ + } + + segment->x1 = x1; + segment->y1 = y1; + segment->x2 = x2; + segment->y2 = y2; + +#ifdef MUSTCOPY + Data (dpy, (char *) &segmentdata, len); +#endif /* MUSTCOPY */ + + UnlockDisplay(dpy); + SyncHandle(); + } + return 1; +} + diff --git a/src/DrLines.c b/src/DrLines.c new file mode 100644 index 00000000..05b0d5d7 --- /dev/null +++ b/src/DrLines.c @@ -0,0 +1,54 @@ +/* $Xorg: DrLines.c,v 1.4 2001/02/09 02:03:32 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XDrawLines (dpy, d, gc, points, npoints, mode) + register Display *dpy; + Drawable d; + GC gc; + XPoint *points; + int npoints; + int mode; +{ + register xPolyLineReq *req; + register long length; + LockDisplay(dpy); + FlushGC(dpy, gc); + GetReq (PolyLine, req); + req->drawable = d; + req->gc = gc->gid; + req->coordMode = mode; + SetReqLen(req, npoints, 65535 - req->length); + /* each point is 2 16-bit integers */ + length = npoints << 2; /* watch out for macros... */ + Data16 (dpy, (short *) points, length); + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} + diff --git a/src/DrPoint.c b/src/DrPoint.c new file mode 100644 index 00000000..390e9dad --- /dev/null +++ b/src/DrPoint.c @@ -0,0 +1,93 @@ +/* $Xorg: DrPoint.c,v 1.4 2001/02/09 02:03:32 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +/* precompute the maximum size of batching request allowed */ + +#define size (SIZEOF(xPolyPointReq) + PTSPERBATCH * SIZEOF(xPoint)) + +XDrawPoint(dpy, d, gc, x, y) + register Display *dpy; + Drawable d; + GC gc; + int x, y; /* INT16 */ +{ + xPoint *point; +#ifdef MUSTCOPY + xPoint pointdata; + long len = SIZEOF(xPoint); + + point = &pointdata; +#endif /* MUSTCOPY */ + + LockDisplay(dpy); + FlushGC(dpy, gc); + + { + register xPolyPointReq *req = (xPolyPointReq *) dpy->last_req; + + + /* if same as previous request, with same drawable, batch requests */ + if ( + (req->reqType == X_PolyPoint) + && (req->drawable == d) + && (req->gc == gc->gid) + && (req->coordMode == CoordModeOrigin) + && ((dpy->bufptr + SIZEOF(xPoint)) <= dpy->bufmax) + && (((char *)dpy->bufptr - (char *)req) < size) ) { + req->length += SIZEOF(xPoint) >> 2; +#ifndef MUSTCOPY + point = (xPoint *) dpy->bufptr; + dpy->bufptr += SIZEOF(xPoint); +#endif /* not MUSTCOPY */ + } + + else { + GetReqExtra(PolyPoint, 4, req); /* 1 point = 4 bytes */ + req->drawable = d; + req->gc = gc->gid; + req->coordMode = CoordModeOrigin; +#ifdef MUSTCOPY + dpy->bufptr -= SIZEOF(xPoint); +#else + point = (xPoint *) NEXTPTR(req,xPolyPointReq); +#endif /* MUSTCOPY */ + } + + point->x = x; + point->y = y; + +#ifdef MUSTCOPY + Data (dpy, (char *) point, len); +#endif /* MUSTCOPY */ + } + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} + diff --git a/src/DrPoints.c b/src/DrPoints.c new file mode 100644 index 00000000..c261be0d --- /dev/null +++ b/src/DrPoints.c @@ -0,0 +1,82 @@ +/* $Xorg: DrPoints.c,v 1.4 2001/02/09 02:03:32 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XDrawPoints(dpy, d, gc, points, n_points, mode) + register Display *dpy; + Drawable d; + GC gc; + XPoint *points; + int n_points; + int mode; /* CoordMode */ +{ + register xPolyPointReq *req; + register long nbytes; + int n; + int xoff, yoff; + XPoint pt; + + xoff = yoff = 0; + LockDisplay(dpy); + FlushGC(dpy, gc); + while (n_points) { + GetReq(PolyPoint, req); + req->drawable = d; + req->gc = gc->gid; + req->coordMode = mode; + n = n_points; + if (!dpy->bigreq_size && n > (dpy->max_request_size - req->length)) + n = dpy->max_request_size - req->length; + SetReqLen(req, n, n); + nbytes = ((long)n) << 2; /* watch out for macros... */ + if (xoff || yoff) { + pt.x = xoff + points->x; + pt.y = yoff + points->y; + Data16 (dpy, (short *) &pt, 4); + if (nbytes > 4) { + Data16 (dpy, (short *) (points + 1), nbytes - 4); + } + } else { + Data16 (dpy, (short *) points, nbytes); + } + n_points -= n; + if (n_points && (mode == CoordModePrevious)) { + register XPoint *pptr = points; + points += n; + while (pptr != points) { + xoff += pptr->x; + yoff += pptr->y; + pptr++; + } + } else + points += n; + } + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} diff --git a/src/DrRect.c b/src/DrRect.c new file mode 100644 index 00000000..0c3c48e4 --- /dev/null +++ b/src/DrRect.c @@ -0,0 +1,95 @@ +/* $Xorg: DrRect.c,v 1.4 2001/02/09 02:03:32 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +/* precompute the maximum size of batching request allowed */ + +#define wsize (SIZEOF(xPolyRectangleReq) + WRCTSPERBATCH * SIZEOF(xRectangle)) +#define zsize (SIZEOF(xPolyRectangleReq) + ZRCTSPERBATCH * SIZEOF(xRectangle)) + +XDrawRectangle(dpy, d, gc, x, y, width, height) + register Display *dpy; + Drawable d; + GC gc; + int x, y; /* INT16 */ + unsigned int width, height; /* CARD16 */ +{ + xRectangle *rect; +#ifdef MUSTCOPY + xRectangle rectdata; + long len = SIZEOF(xRectangle); + + rect = &rectdata; +#endif /* MUSTCOPY */ + + LockDisplay(dpy); + FlushGC(dpy, gc); + + { + register xPolyRectangleReq *req = (xPolyRectangleReq *) dpy->last_req; + + /* if same as previous request, with same drawable, batch requests */ + if ( + (req->reqType == X_PolyRectangle) + && (req->drawable == d) + && (req->gc == gc->gid) + && ((dpy->bufptr + SIZEOF(xRectangle)) <= dpy->bufmax) + && (((char *)dpy->bufptr - (char *)req) < (gc->values.line_width ? + wsize : zsize)) ) { + req->length += SIZEOF(xRectangle) >> 2; +#ifndef MUSTCOPY + rect = (xRectangle *) dpy->bufptr; + dpy->bufptr += SIZEOF(xRectangle); +#endif /* not MUSTCOPY */ + } + + else { + GetReqExtra(PolyRectangle, SIZEOF(xRectangle), req); + req->drawable = d; + req->gc = gc->gid; +#ifdef MUSTCOPY + dpy->bufptr -= SIZEOF(xRectangle); +#else + rect = (xRectangle *) NEXTPTR(req,xPolyRectangleReq); +#endif /* MUSTCOPY */ + } + + rect->x = x; + rect->y = y; + rect->width = width; + rect->height = height; + +#ifdef MUSTCOPY + Data (dpy, (char *) rect, len); /* subtracted bufptr up above */ +#endif /* MUSTCOPY */ + + } + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} diff --git a/src/DrRects.c b/src/DrRects.c new file mode 100644 index 00000000..ac87bd9b --- /dev/null +++ b/src/DrRects.c @@ -0,0 +1,62 @@ +/* $Xorg: DrRects.c,v 1.4 2001/02/09 02:03:32 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XDrawRectangles(dpy, d, gc, rects, n_rects) +register Display *dpy; +Drawable d; +GC gc; +XRectangle *rects; +int n_rects; +{ + register xPolyRectangleReq *req; + long len; + int n; + + LockDisplay(dpy); + FlushGC(dpy, gc); + while (n_rects) { + GetReq(PolyRectangle, req); + req->drawable = d; + req->gc = gc->gid; + n = n_rects; + len = ((long)n) << 1; + if (!dpy->bigreq_size && len > (dpy->max_request_size - req->length)) { + n = (dpy->max_request_size - req->length) >> 1; + len = ((long)n) << 1; + } + SetReqLen(req, len, len); + len <<= 2; /* watch out for macros... */ + Data16 (dpy, (short *) rects, len); + n_rects -= n; + rects += n; + } + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} diff --git a/src/DrSegs.c b/src/DrSegs.c new file mode 100644 index 00000000..41c4ea4a --- /dev/null +++ b/src/DrSegs.c @@ -0,0 +1,63 @@ +/* $Xorg: DrSegs.c,v 1.4 2001/02/09 02:03:32 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XDrawSegments (dpy, d, gc, segments, nsegments) + register Display *dpy; + Drawable d; + GC gc; + XSegment *segments; + int nsegments; +{ + register xPolySegmentReq *req; + long len; + int n; + + LockDisplay(dpy); + FlushGC(dpy, gc); + while (nsegments) { + GetReq (PolySegment, req); + req->drawable = d; + req->gc = gc->gid; + n = nsegments; + len = ((long)n) << 1; + if (!dpy->bigreq_size && len > (dpy->max_request_size - req->length)) { + n = (dpy->max_request_size - req->length) >> 1; + len = ((long)n) << 1; + } + SetReqLen(req, len, len); + len <<= 2; /* watch out for macros... */ + Data16 (dpy, (short *) segments, len); + nsegments -= n; + segments += n; + } + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} + diff --git a/src/ErrDes.c b/src/ErrDes.c new file mode 100644 index 00000000..a7f82cc7 --- /dev/null +++ b/src/ErrDes.c @@ -0,0 +1,196 @@ +/* + * $Xorg: ErrDes.c,v 1.4 2001/02/09 02:03:32 xorgcvs Exp $ + */ + +/*********************************************************** + +Copyright 1987, 1988, 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, 1988 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. + +******************************************************************/ + +#include "Xlibint.h" +#include <X11/Xos.h> +#include "Xresource.h" +#include <stdio.h> + +#ifndef ERRORDB +#define ERRORDB "/usr/lib/X11/XErrorDB" +#endif + +#ifdef __STDC__ +#define Const const +#else +#define Const /**/ +#endif + +/* + * descriptions of errors in Section 4 of Protocol doc (pp. 350-351); more + * verbose descriptions are given in the error database + */ +static Const char * Const _XErrorList[] = { + /* No error */ "no error", + /* BadRequest */ "BadRequest", + /* BadValue */ "BadValue", + /* BadWindow */ "BadWindow", + /* BadPixmap */ "BadPixmap", + /* BadAtom */ "BadAtom", + /* BadCursor */ "BadCursor", + /* BadFont */ "BadFont", + /* BadMatch */ "BadMatch", + /* BadDrawable */ "BadDrawable", + /* BadAccess */ "BadAccess", + /* BadAlloc */ "BadAlloc", + /* BadColor */ "BadColor", + /* BadGC */ "BadGC", + /* BadIDChoice */ "BadIDChoice", + /* BadName */ "BadName", + /* BadLength */ "BadLength", + /* BadImplementation */ "BadImplementation", +}; + + +XGetErrorText(dpy, code, buffer, nbytes) + register int code; + register Display *dpy; + char *buffer; + int nbytes; +{ + char buf[150]; + register _XExtension *ext; + _XExtension *bext = (_XExtension *)NULL; + + if (nbytes == 0) return 0; + if (code <= BadImplementation && code > 0) { + sprintf(buf, "%d", code); + (void) XGetErrorDatabaseText(dpy, "XProtoError", buf, _XErrorList[code], + buffer, nbytes); + } else + buffer[0] = '\0'; + /* call out to any extensions interested */ + for (ext = dpy->ext_procs; ext; ext = ext->next) { + if (ext->error_string) + (*ext->error_string)(dpy, code, &ext->codes, buffer, nbytes); + if (ext->codes.first_error && + ext->codes.first_error < code && + (!bext || ext->codes.first_error > bext->codes.first_error)) + bext = ext; + } + if (!buffer[0] && bext) { + sprintf(buf, "%s.%d", bext->name, code - bext->codes.first_error); + (void) XGetErrorDatabaseText(dpy, "XProtoError", buf, "", buffer, nbytes); + } + if (!buffer[0]) + sprintf(buffer, "%d", code); + return 0; +} + +#if NeedFunctionPrototypes +/*ARGSUSED*/ +XGetErrorDatabaseText( + Display *dpy, + register _Xconst char *name, + register _Xconst char *type, + _Xconst char *defaultp, + char *buffer, + int nbytes) +#else +/*ARGSUSED*/ +XGetErrorDatabaseText(dpy, name, type, defaultp, buffer, nbytes) + Display *dpy; + register char *name, *type; + char *defaultp; + char *buffer; + int nbytes; +#endif +{ + + static XrmDatabase db = NULL; + XrmString type_str; + XrmValue result; + char temp[BUFSIZ]; + char* tptr; + unsigned long tlen; + + if (nbytes == 0) return 0; + + if (!db) { + /* the Xrm routines expect to be called with the global + mutex unlocked. */ + XrmDatabase temp_db; + int do_destroy; + + XrmInitialize(); + temp_db = XrmGetFileDatabase(ERRORDB); + + _XLockMutex(_Xglobal_lock); + if (!db) { + db = temp_db; + do_destroy = 0; + } else + do_destroy = 1; /* we didn't need to get it after all */ + _XUnlockMutex(_Xglobal_lock); + + if (do_destroy) + XrmDestroyDatabase(temp_db); + } + + if (db) + { + tlen = strlen (name) + strlen (type) + 2; + if (tlen <= BUFSIZE) tptr = temp; + else tptr = Xmalloc (tlen); + sprintf(tptr, "%s.%s", name, type); + XrmGetResource(db, tptr, "ErrorType.ErrorNumber", &type_str, &result); + if (tptr != temp) Xfree (tptr); + } + else + result.addr = (XPointer)NULL; + if (!result.addr) { + result.addr = (XPointer) defaultp; + result.size = strlen(defaultp) + 1; + } + (void) strncpy (buffer, (char *) result.addr, nbytes); + if (result.size > nbytes) buffer[nbytes-1] = '\0'; + return 0; +} diff --git a/src/ErrHndlr.c b/src/ErrHndlr.c new file mode 100644 index 00000000..b7f6418b --- /dev/null +++ b/src/ErrHndlr.c @@ -0,0 +1,95 @@ +/* $Xorg: ErrHndlr.c,v 1.4 2001/02/09 02:03:32 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +extern int _XDefaultError(); +extern int _XDefaultIOError(); +/* + * XErrorHandler - This procedure sets the X non-fatal error handler + * (_XErrorFunction) to be the specified routine. If NULL is passed in + * the original error handler is restored. + */ + +#if NeedFunctionPrototypes +XErrorHandler XSetErrorHandler(XErrorHandler handler) +#else +XErrorHandler XSetErrorHandler(handler) + register XErrorHandler handler; +#endif +{ + int (*oldhandler)(); + + _XLockMutex(_Xglobal_lock); + oldhandler = _XErrorFunction; + + if (!oldhandler) + oldhandler = _XDefaultError; + + if (handler != NULL) { + _XErrorFunction = handler; + } + else { + _XErrorFunction = _XDefaultError; + } + _XUnlockMutex(_Xglobal_lock); + + return (XErrorHandler) oldhandler; +} + +/* + * XIOErrorHandler - This procedure sets the X fatal I/O error handler + * (_XIOErrorFunction) to be the specified routine. If NULL is passed in + * the original error handler is restored. + */ + +extern int _XIOError(); +#if NeedFunctionPrototypes +XIOErrorHandler XSetIOErrorHandler(XIOErrorHandler handler) +#else +XIOErrorHandler XSetIOErrorHandler(handler) + register XIOErrorHandler handler; +#endif +{ + int (*oldhandler)(); + + _XLockMutex(_Xglobal_lock); + oldhandler = _XIOErrorFunction; + + if (!oldhandler) + oldhandler = _XDefaultIOError; + + if (handler != NULL) { + _XIOErrorFunction = handler; + } + else { + _XIOErrorFunction = _XDefaultIOError; + } + _XUnlockMutex(_Xglobal_lock); + + return (XIOErrorHandler) oldhandler; +} diff --git a/src/EvToWire.c b/src/EvToWire.c new file mode 100644 index 00000000..361c4e2c --- /dev/null +++ b/src/EvToWire.c @@ -0,0 +1,404 @@ +/* $Xorg: EvToWire.c,v 1.4 2001/02/09 02:03:32 xorgcvs Exp $ */ + +/* + +Copyright 1985, 1986, 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. + +*/ + +/* + * XEvToWire.c - Internal support routines for the C subroutine + * interface library (Xlib) to the X Window System Protocol V11.0. + */ +#define NEED_EVENTS +#define NEED_REPLIES + +#include "Xlibint.h" + +/* + * reformat a wire event into an XEvent structure of the right type. + */ +Status +_XEventToWire(dpy, re, event) +register Display *dpy; /* pointer to display structure */ +register XEvent *re; /* pointer to where event should be reformatted */ +register xEvent *event; /* wire protocol event */ +{ + switch (event->u.u.type = re->type) { + case KeyPress: + case KeyRelease: + { + register XKeyEvent *ev = (XKeyEvent*) re; + event->u.keyButtonPointer.root = ev->root; + event->u.keyButtonPointer.event = ev->window; + event->u.keyButtonPointer.child = ev->subwindow; + event->u.keyButtonPointer.time = ev->time; + event->u.keyButtonPointer.eventX = ev->x ; + event->u.keyButtonPointer.eventY = ev->y ; + event->u.keyButtonPointer.rootX = ev->x_root; + event->u.keyButtonPointer.rootY = ev->y_root; + event->u.keyButtonPointer.state = ev->state; + event->u.keyButtonPointer.sameScreen = ev->same_screen; + event->u.u.detail = ev->keycode; + } + break; + case ButtonPress: + case ButtonRelease: + { + register XButtonEvent *ev = (XButtonEvent *) re; + event->u.keyButtonPointer.root = ev->root; + event->u.keyButtonPointer.event = ev->window; + event->u.keyButtonPointer.child = ev->subwindow; + event->u.keyButtonPointer.time = ev->time; + event->u.keyButtonPointer.eventX = ev->x; + event->u.keyButtonPointer.eventY = ev->y; + event->u.keyButtonPointer.rootX = ev->x_root; + event->u.keyButtonPointer.rootY = ev->y_root; + event->u.keyButtonPointer.state = ev->state; + event->u.keyButtonPointer.sameScreen = ev->same_screen; + event->u.u.detail = ev->button; + } + break; + case MotionNotify: + { + register XMotionEvent *ev = (XMotionEvent *)re; + event->u.keyButtonPointer.root = ev->root; + event->u.keyButtonPointer.event = ev->window; + event->u.keyButtonPointer.child = ev->subwindow; + event->u.keyButtonPointer.time = ev->time; + event->u.keyButtonPointer.eventX= ev->x; + event->u.keyButtonPointer.eventY= ev->y; + event->u.keyButtonPointer.rootX = ev->x_root; + event->u.keyButtonPointer.rootY = ev->y_root; + event->u.keyButtonPointer.state = ev->state; + event->u.keyButtonPointer.sameScreen= ev->same_screen; + event->u.u.detail = ev->is_hint; + } + break; + case EnterNotify: + case LeaveNotify: + { + register XCrossingEvent *ev = (XCrossingEvent *) re; + event->u.enterLeave.root = ev->root; + event->u.enterLeave.event = ev->window; + event->u.enterLeave.child = ev->subwindow; + event->u.enterLeave.time = ev->time; + event->u.enterLeave.eventX = ev->x; + event->u.enterLeave.eventY = ev->y; + event->u.enterLeave.rootX = ev->x_root; + event->u.enterLeave.rootY = ev->y_root; + event->u.enterLeave.state = ev->state; + event->u.enterLeave.mode = ev->mode; + event->u.enterLeave.flags = 0; + if (ev->same_screen) { + event->u.enterLeave.flags |= ELFlagSameScreen; + } + if (ev->focus) { + event->u.enterLeave.flags |= ELFlagFocus; + } + event->u.u.detail = ev->detail; + } + break; + case FocusIn: + case FocusOut: + { + register XFocusChangeEvent *ev = (XFocusChangeEvent *) re; + event->u.focus.window = ev->window; + event->u.focus.mode = ev->mode; + event->u.u.detail = ev->detail; + } + break; + case KeymapNotify: + { + register XKeymapEvent *ev = (XKeymapEvent *) re; + memcpy ((char *)(((xKeymapEvent *) event)->map), + &ev->key_vector[1], + sizeof (((xKeymapEvent *) event)->map)); + } + break; + case Expose: + { + register XExposeEvent *ev = (XExposeEvent *) re; + event->u.expose.window = ev->window; + event->u.expose.x = ev->x; + event->u.expose.y = ev->y; + event->u.expose.width = ev->width; + event->u.expose.height = ev->height; + event->u.expose.count = ev->count; + } + break; + case GraphicsExpose: + { + register XGraphicsExposeEvent *ev = + (XGraphicsExposeEvent *) re; + event->u.graphicsExposure.drawable = ev->drawable; + event->u.graphicsExposure.x = ev->x; + event->u.graphicsExposure.y = ev->y; + event->u.graphicsExposure.width = ev->width; + event->u.graphicsExposure.height = ev->height; + event->u.graphicsExposure.count = ev->count; + event->u.graphicsExposure.majorEvent= ev->major_code; + event->u.graphicsExposure.minorEvent= ev->minor_code; + } + break; + case NoExpose: + { + register XNoExposeEvent *ev = (XNoExposeEvent *) re; + event->u.noExposure.drawable = ev->drawable; + event->u.noExposure.majorEvent = ev->major_code; + event->u.noExposure.minorEvent = ev->minor_code; + } + break; + case VisibilityNotify: + { + register XVisibilityEvent *ev = (XVisibilityEvent *) re; + event->u.visibility.window = ev->window; + event->u.visibility.state = ev->state; + } + break; + case CreateNotify: + { + register XCreateWindowEvent *ev = + (XCreateWindowEvent *) re; + event->u.createNotify.window = ev->window; + event->u.createNotify.parent = ev->parent; + event->u.createNotify.x = ev->x; + event->u.createNotify.y = ev->y; + event->u.createNotify.width = ev->width; + event->u.createNotify.height = ev->height; + event->u.createNotify.borderWidth = ev->border_width; + event->u.createNotify.override = ev->override_redirect; + } + break; + case DestroyNotify: + { + register XDestroyWindowEvent *ev = + (XDestroyWindowEvent *) re; + event->u.destroyNotify.window = ev->window; + event->u.destroyNotify.event = ev->event; + } + break; + case UnmapNotify: + { + register XUnmapEvent *ev = (XUnmapEvent *) re; + event->u.unmapNotify.window = ev->window; + event->u.unmapNotify.event = ev->event; + event->u.unmapNotify.fromConfigure = ev->from_configure; + } + break; + case MapNotify: + { + register XMapEvent *ev = (XMapEvent *) re; + event->u.mapNotify.window = ev->window; + event->u.mapNotify.event = ev->event; + event->u.mapNotify.override = ev->override_redirect; + } + break; + case MapRequest: + { + register XMapRequestEvent *ev = (XMapRequestEvent *) re; + event->u.mapRequest.window = ev->window; + event->u.mapRequest.parent = ev->parent; + } + break; + case ReparentNotify: + { + register XReparentEvent *ev = (XReparentEvent *) re; + event->u.reparent.window = ev->window; + event->u.reparent.event = ev->event; + event->u.reparent.parent = ev->parent; + event->u.reparent.x = ev->x; + event->u.reparent.y = ev->y; + event->u.reparent.override = ev->override_redirect; + } + break; + case ConfigureNotify: + { + register XConfigureEvent *ev = (XConfigureEvent *) re; + event->u.configureNotify.window = ev->window; + event->u.configureNotify.event = ev->event; + event->u.configureNotify.aboveSibling = ev->above; + event->u.configureNotify.x = ev->x; + event->u.configureNotify.y = ev->y; + event->u.configureNotify.width = ev->width; + event->u.configureNotify.height = ev->height; + event->u.configureNotify.borderWidth= ev->border_width; + event->u.configureNotify.override = ev->override_redirect; + } + break; + case ConfigureRequest: + { + register XConfigureRequestEvent *ev = + (XConfigureRequestEvent *) re; + event->u.configureRequest.window = ev->window; + event->u.configureRequest.parent = ev->parent; + event->u.configureRequest.sibling = ev->above; + event->u.configureRequest.x = ev->x; + event->u.configureRequest.y = ev->y; + event->u.configureRequest.width = ev->width; + event->u.configureRequest.height = ev->height; + event->u.configureRequest.borderWidth= ev->border_width; + event->u.configureRequest.valueMask= ev->value_mask; + event->u.u.detail = ev->detail; + } + break; + case GravityNotify: + { + register XGravityEvent *ev = (XGravityEvent *) re; + event->u.gravity.window = ev->window; + event->u.gravity.event = ev->event; + event->u.gravity.x = ev->x; + event->u.gravity.y = ev->y; + } + break; + case ResizeRequest: + { + register XResizeRequestEvent *ev = + (XResizeRequestEvent *) re; + event->u.resizeRequest.window = ev->window; + event->u.resizeRequest.width = ev->width; + event->u.resizeRequest.height = ev->height; + } + break; + case CirculateNotify: + { + register XCirculateEvent *ev = (XCirculateEvent *) re; + event->u.circulate.window = ev->window; + event->u.circulate.event = ev->event; + event->u.circulate.place = ev->place; + } + break; + case CirculateRequest: + { + register XCirculateRequestEvent *ev = + (XCirculateRequestEvent *) re; + event->u.circulate.window = ev->window; + event->u.circulate.event = ev->parent; + event->u.circulate.place = ev->place; + } + break; + case PropertyNotify: + { + register XPropertyEvent *ev = (XPropertyEvent *) re; + event->u.property.window = ev->window; + event->u.property.atom = ev->atom; + event->u.property.time = ev->time; + event->u.property.state = ev->state; + } + break; + case SelectionClear: + { + register XSelectionClearEvent *ev = + (XSelectionClearEvent *) re; + event->u.selectionClear.window = ev->window; + event->u.selectionClear.atom = ev->selection; + event->u.selectionClear.time = ev->time; + } + break; + case SelectionRequest: + { + register XSelectionRequestEvent *ev = + (XSelectionRequestEvent *) re; + event->u.selectionRequest.owner = ev->owner; + event->u.selectionRequest.requestor = ev->requestor; + event->u.selectionRequest.selection = ev->selection; + event->u.selectionRequest.target = ev->target; + event->u.selectionRequest.property = ev->property; + event->u.selectionRequest.time = ev->time; + } + break; + case SelectionNotify: + { + register XSelectionEvent *ev = (XSelectionEvent *) re; + event->u.selectionNotify.requestor = ev->requestor; + event->u.selectionNotify.selection = ev->selection; + event->u.selectionNotify.target = ev->target; + event->u.selectionNotify.property = ev->property; + event->u.selectionNotify.time = ev->time; + } + break; + case ColormapNotify: + { + register XColormapEvent *ev = (XColormapEvent *) re; + event->u.colormap.window = ev->window; + event->u.colormap.colormap = ev->colormap; + event->u.colormap.new = ev->new; + event->u.colormap.state = ev->state; + } + break; + case ClientMessage: + { + register int i; + register XClientMessageEvent *ev + = (XClientMessageEvent *) re; + event->u.clientMessage.window = ev->window; + event->u.u.detail = ev->format; + switch (ev->format) { + case 8: + event->u.clientMessage.u.b.type = ev->message_type; + for (i = 0; i < 20; i++) + event->u.clientMessage.u.b.bytes[i] = ev->data.b[i]; + break; + case 16: + event->u.clientMessage.u.s.type = ev->message_type; + event->u.clientMessage.u.s.shorts0 = ev->data.s[0]; + event->u.clientMessage.u.s.shorts1 = ev->data.s[1]; + event->u.clientMessage.u.s.shorts2 = ev->data.s[2]; + event->u.clientMessage.u.s.shorts3 = ev->data.s[3]; + event->u.clientMessage.u.s.shorts4 = ev->data.s[4]; + event->u.clientMessage.u.s.shorts5 = ev->data.s[5]; + event->u.clientMessage.u.s.shorts6 = ev->data.s[6]; + event->u.clientMessage.u.s.shorts7 = ev->data.s[7]; + event->u.clientMessage.u.s.shorts8 = ev->data.s[8]; + event->u.clientMessage.u.s.shorts9 = ev->data.s[9]; + break; + case 32: + event->u.clientMessage.u.l.type = ev->message_type; + event->u.clientMessage.u.l.longs0 = ev->data.l[0]; + event->u.clientMessage.u.l.longs1 = ev->data.l[1]; + event->u.clientMessage.u.l.longs2 = ev->data.l[2]; + event->u.clientMessage.u.l.longs3 = ev->data.l[3]; + event->u.clientMessage.u.l.longs4 = ev->data.l[4]; + break; + default: + /* client passing bogus data, let server complain */ + break; + } + } + break; + case MappingNotify: + { + register XMappingEvent *ev = (XMappingEvent *) re; + event->u.mappingNotify.firstKeyCode = ev->first_keycode; + event->u.mappingNotify.request = ev->request; + event->u.mappingNotify.count = ev->count; + } + break; + + default: + return(_XUnknownNativeEvent(dpy, re, event)); + } + return(1); +} diff --git a/src/FSSaver.c b/src/FSSaver.c new file mode 100644 index 00000000..57cde1aa --- /dev/null +++ b/src/FSSaver.c @@ -0,0 +1,60 @@ +/* $Xorg: FSSaver.c,v 1.4 2001/02/09 02:03:32 xorgcvs Exp $ */ +/* + +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. + +*/ + +#include "Xlibint.h" + +XActivateScreenSaver(dpy) + register Display *dpy; + +{ + XForceScreenSaver (dpy, ScreenSaverActive); + return 1; +} + +XResetScreenSaver(dpy) + register Display *dpy; + +{ + XForceScreenSaver (dpy, ScreenSaverReset); + return 1; +} + +XForceScreenSaver(dpy, mode) + register Display *dpy; + int mode; + +{ + register xForceScreenSaverReq *req; + + LockDisplay(dpy); + GetReq(ForceScreenSaver, req); + req->mode = mode; + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} + diff --git a/src/FSWrap.c b/src/FSWrap.c new file mode 100644 index 00000000..14adca02 --- /dev/null +++ b/src/FSWrap.c @@ -0,0 +1,273 @@ +/* $Xorg: FSWrap.c,v 1.5 2001/02/09 02:03:32 xorgcvs Exp $ */ + +/* + * Copyright 1991 by the Open Software Foundation + * Copyright 1993 by the TOSHIBA Corp. + * + * 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 Open Software Foundation + * not be used in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. Open Software + * Foundation makes no representations about the suitability of this + * software for any purpose. It is provided "as is" without express or + * implied warranty. + * + * OPEN SOFTWARE FOUNDATION DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL OPEN SOFTWARE FOUNDATIONN 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. + * + * M. Collins OSF + * + * Katsuhisa Yano TOSHIBA Corp. + */ + +/* + +Copyright 1991, 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. + +*/ + +#include "Xlibint.h" +#include "Xlcint.h" +#include <ctype.h> +#include <X11/Xos.h> + + +#define XMAXLIST 256 + +char ** +_XParseBaseFontNameList(str, num) + char *str; + int *num; +{ + char *plist[XMAXLIST]; + char **list; + char *ptr; + + *num = 0; + if (!str || !*str) { + return (char **)NULL; + } + while (*str && isspace(*str)) + str++; + if (!*str) + return (char **)NULL; + + if (!(ptr = Xmalloc((unsigned)strlen(str) + 1))) { + return (char **)NULL; + } + strcpy(ptr, str); + + /* somebody who specifies more than XMAXLIST basefontnames will lose */ + while (*num < (sizeof plist / sizeof plist[0])) { + char *back; + + plist[*num] = ptr; + if ((ptr = strchr(ptr, ','))) { + back = ptr; + } else { + back = plist[*num] + strlen(plist[*num]); + } + while (isspace(*(back - 1))) + back--; + *back = '\0'; + (*num)++; + if (!ptr) + break; + ptr++; + while (*ptr && isspace(*ptr)) + ptr++; + if (!*ptr) + break; + } + if (!(list = (char **) Xmalloc((unsigned)sizeof(char *) * (*num + 1)))) { + Xfree(ptr); + return (char **)NULL; + } + memcpy((char *)list, (char *)plist, sizeof(char *) * (*num)); + *(list + *num) = NULL; + + return list; +} + +static char ** +copy_string_list(string_list, list_count) + char **string_list; + int list_count; +{ + char **string_list_ret, **list_src, **list_dst, *dst; + int length, count; + + if (string_list == NULL) + return (char **) NULL; + + string_list_ret = (char **) Xmalloc(sizeof(char *) * list_count); + if (string_list_ret == NULL) + return (char **) NULL; + + list_src = string_list; + count = list_count; + for (length = 0; count-- > 0; list_src++) + length += strlen(*list_src) + 1; + + dst = (char *) Xmalloc(length); + if (dst == NULL) { + Xfree(string_list_ret); + return (char **) NULL; + } + + list_src = string_list; + count = list_count; + list_dst = string_list_ret; + for ( ; count-- > 0; list_src++) { + strcpy(dst, *list_src); + *list_dst++ = dst; + dst += strlen(dst) + 1; + } + + return string_list_ret; +} + +#if NeedFunctionPrototypes +XFontSet +XCreateFontSet ( + Display *dpy, + _Xconst char *base_font_name_list, + char ***missing_charset_list, + int *missing_charset_count, + char **def_string) +#else +XFontSet +XCreateFontSet (dpy, base_font_name_list, missing_charset_list, + missing_charset_count, def_string) + Display *dpy; + char *base_font_name_list; + char ***missing_charset_list; + int *missing_charset_count; + char **def_string; +#endif +{ + XOM om; + XOC oc; + XOMCharSetList *list; + + *missing_charset_list = NULL; + *missing_charset_count = 0; + + om = XOpenOM(dpy, NULL, NULL, NULL); + if (om == NULL) + return (XFontSet) NULL; + + if ((oc = XCreateOC(om, XNBaseFontName, base_font_name_list, NULL))) { + list = &oc->core.missing_list; + oc->core.om_automatic = True; + } else + list = &om->core.required_charset; + + *missing_charset_list = copy_string_list(list->charset_list, + list->charset_count); + *missing_charset_count = list->charset_count; + + if (list->charset_list && *missing_charset_list == NULL) + oc = NULL; + + if (oc && def_string) { + *def_string = oc->core.default_string; + if (!*def_string) + *def_string = ""; + } + + if (oc == NULL) + XCloseOM(om); + + return (XFontSet) oc; +} + +int +XFontsOfFontSet(font_set, font_struct_list, font_name_list) + XFontSet font_set; + XFontStruct ***font_struct_list; + char ***font_name_list; +{ + *font_name_list = font_set->core.font_info.font_name_list; + *font_struct_list = font_set->core.font_info.font_struct_list; + return font_set->core.font_info.num_font; +} + +char * +XBaseFontNameListOfFontSet(font_set) + XFontSet font_set; +{ + return font_set->core.base_name_list; +} + +char * +XLocaleOfFontSet(font_set) + XFontSet font_set; +{ + return font_set->core.om->core.lcd->core->name; +} + +extern Bool XContextDependentDrawing(font_set) + XFontSet font_set; +{ + return font_set->core.om->core.context_dependent; +} + +Bool +XDirectionalDependentDrawing(font_set) + XFontSet font_set; +{ + return font_set->core.om->core.directional_dependent; +} + +Bool +XContextualDrawing(font_set) + XFontSet font_set; +{ + return font_set->core.om->core.contextual_drawing; +} + +XFontSetExtents * +XExtentsOfFontSet(font_set) + XFontSet font_set; +{ + return &font_set->core.font_set_extents; +} + +void +XFreeFontSet(dpy, font_set) + Display *dpy; + XFontSet font_set; +{ + XCloseOM(font_set->core.om); +} diff --git a/src/FetchName.c b/src/FetchName.c new file mode 100644 index 00000000..1317fa86 --- /dev/null +++ b/src/FetchName.c @@ -0,0 +1,93 @@ +/* $Xorg: FetchName.c,v 1.4 2001/02/09 02:03:32 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include <X11/Xlibint.h> +#include <X11/Xatom.h> +#include <X11/Xos.h> +#include <stdio.h> + + +Status XFetchName (dpy, w, name) + register Display *dpy; + Window w; + char **name; +{ + Atom actual_type; + int actual_format; + unsigned long nitems; + unsigned long leftover; + unsigned char *data = NULL; + if (XGetWindowProperty(dpy, w, XA_WM_NAME, 0L, (long)BUFSIZ, False, XA_STRING, + &actual_type, + &actual_format, &nitems, &leftover, &data) != Success) { + *name = NULL; + return (0); + } + if ( (actual_type == XA_STRING) && (actual_format == 8) ) { + + /* The data returned by XGetWindowProperty is guarranteed to + contain one extra byte that is null terminated to make retrieveing + string properties easy. */ + + *name = (char *)data; + return(1); + } + if (data) Xfree ((char *)data); + *name = NULL; + return(0); +} + +Status XGetIconName (dpy, w, icon_name) + register Display *dpy; + Window w; + char **icon_name; +{ + Atom actual_type; + int actual_format; + unsigned long nitems; + unsigned long leftover; + unsigned char *data = NULL; + if (XGetWindowProperty(dpy, w, XA_WM_ICON_NAME, 0L, (long)BUFSIZ, False, + XA_STRING, + &actual_type, + &actual_format, &nitems, &leftover, &data) != Success) { + *icon_name = NULL; + return (0); + } + if ( (actual_type == XA_STRING) && (actual_format == 8) ) { + + /* The data returned by XGetWindowProperty is guarranteed to + contain one extra byte that is null terminated to make retrieveing + string properties easy. */ + + *icon_name = (char*)data; + return(1); + } + if (data) Xfree ((char *)data); + *icon_name = NULL; + return(0); +} diff --git a/src/FillArc.c b/src/FillArc.c new file mode 100644 index 00000000..22e41910 --- /dev/null +++ b/src/FillArc.c @@ -0,0 +1,96 @@ +/* $Xorg: FillArc.c,v 1.4 2001/02/09 02:03:32 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +/* precompute the maximum size of batching request allowed */ + +#define size (SIZEOF(xPolyFillArcReq) + FARCSPERBATCH * SIZEOF(xArc)) + +XFillArc(dpy, d, gc, x, y, width, height, angle1, angle2) + register Display *dpy; + Drawable d; + GC gc; + int x, y; /* INT16 */ + unsigned int width, height; /* CARD16 */ + int angle1, angle2; /* INT16 */ +{ + xArc *arc; +#ifdef MUSTCOPY + xArc arcdata; + long len = SIZEOF(xArc); + + arc = &arcdata; +#endif /* MUSTCOPY */ + + LockDisplay(dpy); + FlushGC(dpy, gc); + + { + register xPolyFillArcReq *req = (xPolyFillArcReq *) dpy->last_req; + + /* if same as previous request, with same drawable, batch requests */ + if ( + (req->reqType == X_PolyFillArc) + && (req->drawable == d) + && (req->gc == gc->gid) + && ((dpy->bufptr + SIZEOF(xArc)) <= dpy->bufmax) + && (((char *)dpy->bufptr - (char *)req) < size) ) { + req->length += SIZEOF(xArc) >> 2; +#ifndef MUSTCOPY + arc = (xArc *) dpy->bufptr; + dpy->bufptr += SIZEOF(xArc); +#endif /* not MUSTCOPY */ + } + + else { + GetReqExtra(PolyFillArc, SIZEOF(xArc), req); + + req->drawable = d; + req->gc = gc->gid; +#ifdef MUSTCOPY + dpy->bufptr -= SIZEOF(xArc); +#else + arc = (xArc *) NEXTPTR(req,xPolyFillArcReq); +#endif /* MUSTCOPY */ + } + arc->x = x; + arc->y = y; + arc->width = width; + arc->height = height; + arc->angle1 = angle1; + arc->angle2 = angle2; + +#ifdef MUSTCOPY + Data (dpy, (char *) arc, len); +#endif /* MUSTCOPY */ + + } + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} diff --git a/src/FillArcs.c b/src/FillArcs.c new file mode 100644 index 00000000..115f25cc --- /dev/null +++ b/src/FillArcs.c @@ -0,0 +1,64 @@ +/* $Xorg: FillArcs.c,v 1.4 2001/02/09 02:03:32 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +#define arc_scale (SIZEOF(xArc) / 4) + +XFillArcs(dpy, d, gc, arcs, n_arcs) +register Display *dpy; +Drawable d; +GC gc; +XArc *arcs; +int n_arcs; +{ + register xPolyFillArcReq *req; + long len; + int n; + + LockDisplay(dpy); + FlushGC(dpy, gc); + while (n_arcs) { + GetReq(PolyFillArc, req); + req->drawable = d; + req->gc = gc->gid; + n = n_arcs; + len = ((long)n) * arc_scale; + if (!dpy->bigreq_size && len > (dpy->max_request_size - req->length)) { + n = (dpy->max_request_size - req->length) / arc_scale; + len = ((long)n) * arc_scale; + } + SetReqLen(req, len, len); + len <<= 2; /* watch out for macros... */ + Data16 (dpy, (short *) arcs, len); + n_arcs -= n; + arcs += n; + } + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} diff --git a/src/FillPoly.c b/src/FillPoly.c new file mode 100644 index 00000000..c8f40c63 --- /dev/null +++ b/src/FillPoly.c @@ -0,0 +1,61 @@ +/* $Xorg: FillPoly.c,v 1.4 2001/02/09 02:03:32 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XFillPolygon(dpy, d, gc, points, n_points, shape, mode) +register Display *dpy; +Drawable d; +GC gc; +XPoint *points; +int n_points; +int shape; +int mode; +{ + register xFillPolyReq *req; + register long nbytes; + + LockDisplay(dpy); + FlushGC(dpy, gc); + GetReq(FillPoly, req); + + req->drawable = d; + req->gc = gc->gid; + req->shape = shape; + req->coordMode = mode; + + SetReqLen(req, n_points, 65535 - req->length); + + /* shift (mult. by 4) before passing to the (possible) macro */ + + nbytes = n_points << 2; + + Data16 (dpy, (short *) points, nbytes); + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} diff --git a/src/FillRct.c b/src/FillRct.c new file mode 100644 index 00000000..d2537c7c --- /dev/null +++ b/src/FillRct.c @@ -0,0 +1,92 @@ +/* $Xorg: FillRct.c,v 1.4 2001/02/09 02:03:32 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +/* precompute the maximum size of batching request allowed */ + +#define size (SIZEOF(xPolyFillRectangleReq) + FRCTSPERBATCH * SIZEOF(xRectangle)) + +XFillRectangle(dpy, d, gc, x, y, width, height) + register Display *dpy; + Drawable d; + GC gc; + int x, y; /* INT16 */ + unsigned int width, height; /* CARD16 */ +{ + xRectangle *rect; +#ifdef MUSTCOPY + xRectangle rectdata; + long len = SIZEOF(xRectangle); + + rect = &rectdata; +#endif /* MUSTCOPY */ + + LockDisplay(dpy); + FlushGC(dpy, gc); + + { + register xPolyFillRectangleReq *req + = (xPolyFillRectangleReq *) dpy->last_req; + + /* if same as previous request, with same drawable, batch requests */ + if ( + (req->reqType == X_PolyFillRectangle) + && (req->drawable == d) + && (req->gc == gc->gid) + && ((dpy->bufptr + SIZEOF(xRectangle)) <= dpy->bufmax) + && (((char *)dpy->bufptr - (char *)req) < size) ) { + req->length += SIZEOF(xRectangle) >> 2; +#ifndef MUSTCOPY + rect = (xRectangle *) dpy->bufptr; + dpy->bufptr += SIZEOF(xRectangle); +#endif /* not MUSTCOPY */ + } + + else { + GetReqExtra(PolyFillRectangle, SIZEOF(xRectangle), req); + req->drawable = d; + req->gc = gc->gid; +#ifdef MUSTCOPY + dpy->bufptr -= SIZEOF(xRectangle); +#else + rect = (xRectangle *) NEXTPTR(req,xPolyFillRectangleReq); +#endif /* MUSTCOPY */ + } + rect->x = x; + rect->y = y; + rect->width = width; + rect->height = height; + +#ifdef MUSTCOPY + Data (dpy, (char *) rect, len); +#endif /* MUSTCOPY */ + } + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} diff --git a/src/FillRcts.c b/src/FillRcts.c new file mode 100644 index 00000000..4e86fec3 --- /dev/null +++ b/src/FillRcts.c @@ -0,0 +1,63 @@ +/* $Xorg: FillRcts.c,v 1.4 2001/02/09 02:03:33 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XFillRectangles(dpy, d, gc, rectangles, n_rects) +register Display *dpy; +Drawable d; +GC gc; +XRectangle *rectangles; +int n_rects; +{ + register xPolyFillRectangleReq *req; + long len; + int n; + + LockDisplay(dpy); + FlushGC(dpy, gc); + while (n_rects) { + GetReq(PolyFillRectangle, req); + req->drawable = d; + req->gc = gc->gid; + n = n_rects; + len = ((long)n) << 1; + if (!dpy->bigreq_size && len > (dpy->max_request_size - req->length)) { + n = (dpy->max_request_size - req->length) >> 1; + len = ((long)n) << 1; + } + SetReqLen(req, len, len); + len <<= 2; /* watch out for macros... */ + Data16 (dpy, (short *) rectangles, len); + n_rects -= n; + rectangles += n; + } + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} + diff --git a/src/FilterEv.c b/src/FilterEv.c new file mode 100644 index 00000000..2b104839 --- /dev/null +++ b/src/FilterEv.c @@ -0,0 +1,104 @@ +/* $Xorg: FilterEv.c,v 1.4 2001/02/09 02:03:33 xorgcvs Exp $ */ + + /* + * Copyright 1990, 1991 by OMRON Corporation + * + * 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 OMRON not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. OMRON makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * OMRON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL OMRON 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 + * TORTUOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Author: Seiji Kuwari OMRON Corporation + * kuwa@omron.co.jp + * kuwa%omron.co.jp@uunet.uu.net + */ + +/* + +Copyright 1991, 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. + +*/ + +#define NEED_EVENTS +#include "Xlibint.h" +#include "Xlcint.h" + +#ifdef __STDC__ +#define Const const +#else +#define Const /**/ +#endif +extern long Const _Xevent_to_mask[]; + +/* + * Look up if there is a specified filter for the event. + */ +Bool +XFilterEvent(ev, window) + XEvent *ev; + Window window; +{ + XFilterEventList p; + Window win; + long mask; + Bool ret; + + if (window) + win = window; + else + win = ev->xany.window; + if (ev->type >= LASTEvent) + mask = 0; + else + mask = _Xevent_to_mask[ev->type]; + + LockDisplay(ev->xany.display); + for (p = ev->xany.display->im_filters; p != NULL; p = p->next) { + if (win == p->window) { + if ((mask & p->event_mask) || + (ev->type >= p->start_type && ev->type <= p->end_type)) { + ret = (*(p->filter))(ev->xany.display, p->window, ev, + p->client_data); + UnlockDisplay(ev->xany.display); + return(ret); + } + } + } + UnlockDisplay(ev->xany.display); + return(False); +} diff --git a/src/Flush.c b/src/Flush.c new file mode 100644 index 00000000..fd6b3935 --- /dev/null +++ b/src/Flush.c @@ -0,0 +1,40 @@ +/* $Xorg: Flush.c,v 1.4 2001/02/09 02:03:33 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +/* Flush all buffered output requests. */ +/* NOTE: NOT necessary when calling any of the Xlib routines. */ + +XFlush (dpy) + register Display *dpy; + { + LockDisplay(dpy); + _XFlush (dpy); + UnlockDisplay(dpy); + return 1; + } diff --git a/src/Font.c b/src/Font.c new file mode 100644 index 00000000..2b1eae84 --- /dev/null +++ b/src/Font.c @@ -0,0 +1,241 @@ +/* $Xorg: Font.c,v 1.4 2001/02/09 02:03:33 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#define NEED_REPLIES +#include "Xlibint.h" + +static XFontStruct *_XQueryFont(); + +#if NeedFunctionPrototypes +XFontStruct *XLoadQueryFont( + register Display *dpy, + _Xconst char *name) +#else +XFontStruct *XLoadQueryFont(dpy, name) + register Display *dpy; + char *name; +#endif +{ + XFontStruct *font_result; + register long nbytes; + Font fid; + xOpenFontReq *req; + unsigned long seq; + + LockDisplay(dpy); + GetReq(OpenFont, req); + seq = dpy->request; + nbytes = req->nbytes = name ? strlen(name) : 0; + req->fid = fid = XAllocID(dpy); + req->length += (nbytes+3)>>2; + Data (dpy, name, nbytes); + font_result = _XQueryFont(dpy, fid, seq); + UnlockDisplay(dpy); + SyncHandle(); + return font_result; +} + +XFreeFont(dpy, fs) + register Display *dpy; + XFontStruct *fs; +{ + register xResourceReq *req; + register _XExtension *ext; + + LockDisplay(dpy); + /* call out to any extensions interested */ + for (ext = dpy->ext_procs; ext; ext = ext->next) + if (ext->free_Font) (*ext->free_Font)(dpy, fs, &ext->codes); + GetResReq (CloseFont, fs->fid, req); + UnlockDisplay(dpy); + SyncHandle(); + _XFreeExtData(fs->ext_data); + if (fs->per_char) + Xfree ((char *) fs->per_char); + if (fs->properties) + Xfree ((char *) fs->properties); + Xfree ((char *) fs); + return 1; +} + +static XFontStruct * +_XQueryFont (dpy, fid, seq) + register Display *dpy; + Font fid; + unsigned long seq; +{ + register XFontStruct *fs; + register long nbytes; + xQueryFontReply reply; + register xResourceReq *req; + register _XExtension *ext; + _XAsyncHandler async; + _XAsyncErrorState async_state; + + if (seq) { + async_state.min_sequence_number = seq; + async_state.max_sequence_number = seq; + async_state.error_code = BadName; + async_state.major_opcode = X_OpenFont; + async_state.minor_opcode = 0; + async_state.error_count = 0; + async.next = dpy->async_handlers; + async.handler = _XAsyncErrorHandler; + async.data = (XPointer)&async_state; + dpy->async_handlers = &async; + } + GetResReq(QueryFont, fid, req); + if (!_XReply (dpy, (xReply *) &reply, + ((SIZEOF(xQueryFontReply) - SIZEOF(xReply)) >> 2), xFalse)) { + if (seq) + DeqAsyncHandler(dpy, &async); + return (XFontStruct *)NULL; + } + if (seq) + DeqAsyncHandler(dpy, &async); + if (! (fs = (XFontStruct *) Xmalloc (sizeof (XFontStruct)))) { + _XEatData(dpy, (unsigned long)(reply.nFontProps * SIZEOF(xFontProp) + + reply.nCharInfos * SIZEOF(xCharInfo))); + return (XFontStruct *)NULL; + } + fs->ext_data = NULL; + fs->fid = fid; + fs->direction = reply.drawDirection; + fs->min_char_or_byte2 = reply.minCharOrByte2; + fs->max_char_or_byte2 = reply.maxCharOrByte2; + fs->min_byte1 = reply.minByte1; + fs->max_byte1 = reply.maxByte1; + fs->default_char = reply.defaultChar; + fs->all_chars_exist = reply.allCharsExist; + fs->ascent = cvtINT16toInt (reply.fontAscent); + fs->descent = cvtINT16toInt (reply.fontDescent); + +#ifdef MUSTCOPY + { + xCharInfo *xcip; + + xcip = (xCharInfo *) &reply.minBounds; + fs->min_bounds.lbearing = cvtINT16toShort(xcip->leftSideBearing); + fs->min_bounds.rbearing = cvtINT16toShort(xcip->rightSideBearing); + fs->min_bounds.width = cvtINT16toShort(xcip->characterWidth); + fs->min_bounds.ascent = cvtINT16toShort(xcip->ascent); + fs->min_bounds.descent = cvtINT16toShort(xcip->descent); + fs->min_bounds.attributes = xcip->attributes; + + xcip = (xCharInfo *) &reply.maxBounds; + fs->max_bounds.lbearing = cvtINT16toShort(xcip->leftSideBearing); + fs->max_bounds.rbearing = cvtINT16toShort(xcip->rightSideBearing); + fs->max_bounds.width = cvtINT16toShort(xcip->characterWidth); + fs->max_bounds.ascent = cvtINT16toShort(xcip->ascent); + fs->max_bounds.descent = cvtINT16toShort(xcip->descent); + fs->max_bounds.attributes = xcip->attributes; + } +#else + /* XXX the next two statements won't work if short isn't 16 bits */ + fs->min_bounds = * (XCharStruct *) &reply.minBounds; + fs->max_bounds = * (XCharStruct *) &reply.maxBounds; +#endif /* MUSTCOPY */ + + fs->n_properties = reply.nFontProps; + /* + * if no properties defined for the font, then it is bad + * font, but shouldn't try to read nothing. + */ + fs->properties = NULL; + if (fs->n_properties > 0) { + nbytes = reply.nFontProps * sizeof(XFontProp); + fs->properties = (XFontProp *) Xmalloc ((unsigned) nbytes); + nbytes = reply.nFontProps * SIZEOF(xFontProp); + if (! fs->properties) { + Xfree((char *) fs); + _XEatData(dpy, (unsigned long) + (nbytes + reply.nCharInfos * SIZEOF(xCharInfo))); + return (XFontStruct *)NULL; + } + _XRead32 (dpy, (char *)fs->properties, nbytes); + } + /* + * If no characters in font, then it is a bad font, but + * shouldn't try to read nothing. + */ + /* have to unpack charinfos on some machines (CRAY) */ + fs->per_char = NULL; + if (reply.nCharInfos > 0){ + nbytes = reply.nCharInfos * sizeof(XCharStruct); + if (! (fs->per_char = (XCharStruct *) Xmalloc ((unsigned) nbytes))) { + if (fs->properties) Xfree((char *) fs->properties); + Xfree((char *) fs); + _XEatData(dpy, (unsigned long) + (reply.nCharInfos * SIZEOF(xCharInfo))); + return (XFontStruct *)NULL; + } + +#ifdef MUSTCOPY + { + register XCharStruct *cs = fs->per_char; + register int i; + + for (i = 0; i < reply.nCharInfos; i++, cs++) { + xCharInfo xcip; + + _XRead(dpy, (char *)&xcip, SIZEOF(xCharInfo)); + cs->lbearing = cvtINT16toShort(xcip.leftSideBearing); + cs->rbearing = cvtINT16toShort(xcip.rightSideBearing); + cs->width = cvtINT16toShort(xcip.characterWidth); + cs->ascent = cvtINT16toShort(xcip.ascent); + cs->descent = cvtINT16toShort(xcip.descent); + cs->attributes = xcip.attributes; + } + } +#else + nbytes = reply.nCharInfos * SIZEOF(xCharInfo); + _XRead16 (dpy, (char *)fs->per_char, nbytes); +#endif + } + + /* call out to any extensions interested */ + for (ext = dpy->ext_procs; ext; ext = ext->next) + if (ext->create_Font) (*ext->create_Font)(dpy, fs, &ext->codes); + return fs; +} + + +XFontStruct *XQueryFont (dpy, fid) + register Display *dpy; + Font fid; +{ + XFontStruct *font_result; + + LockDisplay(dpy); + font_result = _XQueryFont(dpy, fid, 0L); + UnlockDisplay(dpy); + SyncHandle(); + return font_result; +} + + + diff --git a/src/FontInfo.c b/src/FontInfo.c new file mode 100644 index 00000000..2dd4e793 --- /dev/null +++ b/src/FontInfo.c @@ -0,0 +1,248 @@ +/* $Xorg: FontInfo.c,v 1.4 2001/02/09 02:03:33 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#define NEED_REPLIES +#include "Xlibint.h" + +#if NeedFunctionPrototypes +char **XListFontsWithInfo( +register Display *dpy, +_Xconst char *pattern, /* null-terminated */ +int maxNames, +int *actualCount, /* RETURN */ +XFontStruct **info) /* RETURN */ +#else +char **XListFontsWithInfo(dpy, pattern, maxNames, actualCount, info) +register Display *dpy; +char *pattern; /* null-terminated */ +int maxNames; +int *actualCount; /* RETURN */ +XFontStruct **info; /* RETURN */ +#endif +{ + register long nbytes; + register int i; + register XFontStruct *fs; + register int size = 0; + XFontStruct *finfo = NULL; + char **flist = NULL; + xListFontsWithInfoReply reply; + register xListFontsReq *req; + int j; + + LockDisplay(dpy); + GetReq(ListFontsWithInfo, req); + req->maxNames = maxNames; + nbytes = req->nbytes = pattern ? strlen (pattern) : 0; + req->length += (nbytes + 3) >> 2; + _XSend (dpy, pattern, nbytes); + /* use _XSend instead of Data, since subsequent _XReply will flush buffer */ + + for (i = 0; ; i++) { + if (!_XReply (dpy, (xReply *) &reply, + ((SIZEOF(xListFontsWithInfoReply) - + SIZEOF(xGenericReply)) >> 2), xFalse)) { + for (j=(i-1); (j >= 0); j--) { + Xfree(flist[j]); + if (finfo[j].properties) Xfree((char *) finfo[j].properties); + } + if (flist) Xfree((char *) flist); + if (finfo) Xfree((char *) finfo); + UnlockDisplay(dpy); + SyncHandle(); + return ((char **) NULL); + } + if (reply.nameLength == 0) + break; + if ((i + reply.nReplies) >= size) { + size = i + reply.nReplies + 1; + + if (finfo) { + XFontStruct * tmp_finfo = (XFontStruct *) + Xrealloc ((char *) finfo, + (unsigned) (sizeof(XFontStruct) * size)); + char ** tmp_flist = (char **) + Xrealloc ((char *) flist, + (unsigned) (sizeof(char *) * (size+1))); + + if ((! tmp_finfo) || (! tmp_flist)) { + /* free all the memory that we allocated */ + for (j=(i-1); (j >= 0); j--) { + Xfree(flist[j]); + if (finfo[j].properties) + Xfree((char *) finfo[j].properties); + } + if (tmp_flist) Xfree((char *) tmp_flist); + else Xfree((char *) flist); + if (tmp_finfo) Xfree((char *) tmp_finfo); + else Xfree((char *) finfo); + goto clearwire; + } + finfo = tmp_finfo; + flist = tmp_flist; + } + else { + if (! (finfo = (XFontStruct *) + Xmalloc((unsigned) (sizeof(XFontStruct) * size)))) + goto clearwire; + if (! (flist = (char **) + Xmalloc((unsigned) (sizeof(char *) * (size+1))))) { + Xfree((char *) finfo); + goto clearwire; + } + } + } + fs = &finfo[i]; + + fs->ext_data = NULL; + fs->per_char = NULL; + fs->fid = None; + fs->direction = reply.drawDirection; + fs->min_char_or_byte2 = reply.minCharOrByte2; + fs->max_char_or_byte2 = reply.maxCharOrByte2; + fs->min_byte1 = reply.minByte1; + fs->max_byte1 = reply.maxByte1; + fs->default_char = reply.defaultChar; + fs->all_chars_exist = reply.allCharsExist; + fs->ascent = cvtINT16toInt (reply.fontAscent); + fs->descent = cvtINT16toInt (reply.fontDescent); + +#ifdef MUSTCOPY + { + xCharInfo *xcip; + + xcip = (xCharInfo *) &reply.minBounds; + fs->min_bounds.lbearing = xcip->leftSideBearing; + fs->min_bounds.rbearing = xcip->rightSideBearing; + fs->min_bounds.width = xcip->characterWidth; + fs->min_bounds.ascent = xcip->ascent; + fs->min_bounds.descent = xcip->descent; + fs->min_bounds.attributes = xcip->attributes; + + xcip = (xCharInfo *) &reply.maxBounds; + fs->max_bounds.lbearing = xcip->leftSideBearing; + fs->max_bounds.rbearing = xcip->rightSideBearing; + fs->max_bounds.width = xcip->characterWidth; + fs->max_bounds.ascent = xcip->ascent; + fs->max_bounds.descent = xcip->descent; + fs->max_bounds.attributes = xcip->attributes; + } +#else + /* XXX the next two statements won't work if short isn't 16 bits */ + fs->min_bounds = * (XCharStruct *) &reply.minBounds; + fs->max_bounds = * (XCharStruct *) &reply.maxBounds; +#endif /* MUSTCOPY */ + + fs->n_properties = reply.nFontProps; + if (fs->n_properties > 0) { + nbytes = reply.nFontProps * sizeof(XFontProp); + if (! (fs->properties = (XFontProp *) Xmalloc((unsigned) nbytes))) + goto badmem; + nbytes = reply.nFontProps * SIZEOF(xFontProp); + _XRead32 (dpy, (char *)fs->properties, nbytes); + + } else + fs->properties = NULL; + + j = reply.nameLength + 1; + if (!i) + j++; /* make first string 1 byte longer, to match XListFonts */ + flist[i] = (char *) Xmalloc ((unsigned int) j); + if (! flist[i]) { + if (finfo[i].properties) Xfree((char *) finfo[i].properties); + nbytes = reply.nameLength + 3 & ~3; + _XEatData(dpy, (unsigned long) nbytes); + goto badmem; + } + if (!i) { + *flist[0] = 0; /* zero to distinguish from XListFonts */ + flist[0]++; + } + flist[i][reply.nameLength] = '\0'; + _XReadPad (dpy, flist[i], (long) reply.nameLength); + } + *info = finfo; + *actualCount = i; + if (flist) + flist[i] = NULL; /* required in case XFreeFontNames is called */ + UnlockDisplay(dpy); + SyncHandle(); + return (flist); + + + badmem: + /* Free all memory allocated by this function. */ + for (j=(i-1); (j >= 0); j--) { + Xfree(flist[j]); + if (finfo[j].properties) Xfree((char *) finfo[j].properties); + } + if (flist) Xfree((char *) flist); + if (finfo) Xfree((char *) finfo); + + clearwire: + /* Clear the wire. */ + do { + if (reply.nFontProps) + _XEatData(dpy, (unsigned long) + (reply.nFontProps * SIZEOF(xFontProp))); + nbytes = (reply.nameLength + 3) & ~3; + _XEatData(dpy, (unsigned long) nbytes); + } + while (_XReply(dpy,(xReply *) &reply, ((SIZEOF(xListFontsWithInfoReply) - + SIZEOF(xGenericReply)) >> 2), + xFalse) && (reply.nameLength != 0)); + + UnlockDisplay(dpy); + SyncHandle(); + return (char **) NULL; +} + + +XFreeFontInfo (names, info, actualCount) +char **names; +XFontStruct *info; +int actualCount; +{ + register int i; + if (names) { + Xfree (names[0]-1); + for (i = 1; i < actualCount; i++) { + Xfree (names[i]); + } + Xfree((char *) names); + } + if (info) { + for (i = 0; i < actualCount; i++) { + if (info[i].per_char) + Xfree ((char *) info[i].per_char); + if (info[i].properties) + Xfree ((char *) info[i].properties); + } + Xfree((char *) info); + } + return 1; +} diff --git a/src/FontNames.c b/src/FontNames.c new file mode 100644 index 00000000..8432b2f9 --- /dev/null +++ b/src/FontNames.c @@ -0,0 +1,118 @@ +/* $Xorg: FontNames.c,v 1.4 2001/02/09 02:03:33 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#define NEED_REPLIES +#include "Xlibint.h" + +#if NeedFunctionPrototypes +char **XListFonts( +register Display *dpy, +_Xconst char *pattern, /* null-terminated */ +int maxNames, +int *actualCount) /* RETURN */ +#else +char **XListFonts(dpy, pattern, maxNames, actualCount) +register Display *dpy; +char *pattern; /* null-terminated */ +int maxNames; +int *actualCount; /* RETURN */ +#endif +{ + register long nbytes; + register unsigned i; + register int length; + char **flist; + char *ch; + xListFontsReply rep; + register xListFontsReq *req; + register long rlen; + + LockDisplay(dpy); + GetReq(ListFonts, req); + req->maxNames = maxNames; + nbytes = req->nbytes = pattern ? strlen (pattern) : 0; + req->length += (nbytes + 3) >> 2; + _XSend (dpy, pattern, nbytes); + /* use _XSend instead of Data, since following _XReply will flush buffer */ + + if (!_XReply (dpy, (xReply *)&rep, 0, xFalse)) { + *actualCount = 0; + UnlockDisplay(dpy); + SyncHandle(); + return (char **) NULL; + } + + if (rep.nFonts) { + flist = (char **)Xmalloc ((unsigned)rep.nFonts * sizeof(char *)); + rlen = rep.length << 2; + ch = (char *) Xmalloc((unsigned) (rlen + 1)); + /* +1 to leave room for last null-terminator */ + + if ((! flist) || (! ch)) { + if (flist) Xfree((char *) flist); + if (ch) Xfree(ch); + _XEatData(dpy, (unsigned long) rlen); + *actualCount = 0; + UnlockDisplay(dpy); + SyncHandle(); + return (char **) NULL; + } + + _XReadPad (dpy, ch, rlen); + /* + * unpack into null terminated strings. + */ + length = *(unsigned char *)ch; + *ch = 1; /* make sure it is non-zero for XFreeFontNames */ + for (i = 0; i < rep.nFonts; i++) { + flist[i] = ch + 1; /* skip over length */ + ch += length + 1; /* find next length ... */ + length = *(unsigned char *)ch; + *ch = '\0'; /* and replace with null-termination */ + } + } + else flist = (char **) NULL; + *actualCount = rep.nFonts; + UnlockDisplay(dpy); + SyncHandle(); + return (flist); +} + +XFreeFontNames(list) +char **list; +{ + if (list) { + if (!*(list[0]-1)) { /* from ListFontsWithInfo */ + register char **names; + for (names = list+1; *names; names++) + Xfree (*names); + } + Xfree (list[0]-1); + Xfree ((char *)list); + } + return 1; +} diff --git a/src/FreeCmap.c b/src/FreeCmap.c new file mode 100644 index 00000000..3a2d370c --- /dev/null +++ b/src/FreeCmap.c @@ -0,0 +1,46 @@ +/* $Xorg: FreeCmap.c,v 1.4 2001/02/09 02:03:33 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +extern void _XcmsDeleteCmapRec(); + +XFreeColormap(dpy, cmap) +register Display *dpy; +Colormap cmap; +{ + register xResourceReq *req; + + LockDisplay(dpy); + GetResReq(FreeColormap, cmap, req); + + UnlockDisplay(dpy); + SyncHandle(); + + _XcmsDeleteCmapRec(dpy, cmap); + return 1; +} diff --git a/src/FreeCols.c b/src/FreeCols.c new file mode 100644 index 00000000..03f74b90 --- /dev/null +++ b/src/FreeCols.c @@ -0,0 +1,54 @@ +/* $Xorg: FreeCols.c,v 1.4 2001/02/09 02:03:33 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XFreeColors(dpy, cmap, pixels, npixels, planes) +register Display *dpy; +Colormap cmap; +unsigned long *pixels; /* LISTofCARD32 */ +int npixels; +unsigned long planes; /* CARD32 */ +{ + register xFreeColorsReq *req; + register long nbytes; + + LockDisplay(dpy); + GetReq(FreeColors, req); + req->cmap = cmap; + req->planeMask = planes; + + /* on the VAX, each pixel is a 32-bit (unsigned) integer */ + req->length += npixels; + + nbytes = npixels << 2; /* watch out for macros... */ + Data32 (dpy, (long *) pixels, nbytes); + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} + diff --git a/src/FreeCurs.c b/src/FreeCurs.c new file mode 100644 index 00000000..4fe214a9 --- /dev/null +++ b/src/FreeCurs.c @@ -0,0 +1,41 @@ +/* $Xorg: FreeCurs.c,v 1.4 2001/02/09 02:03:33 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XFreeCursor(dpy, cursor) + register Display *dpy; + Cursor cursor; +{ + register xResourceReq *req; + LockDisplay(dpy); + GetResReq(FreeCursor, cursor, req); + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} + diff --git a/src/FreeEData.c b/src/FreeEData.c new file mode 100644 index 00000000..14344fb8 --- /dev/null +++ b/src/FreeEData.c @@ -0,0 +1,43 @@ +/* $Xorg: FreeEData.c,v 1.4 2001/02/09 02:03:33 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +_XFreeExtData (extension) + XExtData *extension; +{ + XExtData *temp; + while (extension) { + if (extension->free_private) + (*extension->free_private)(extension); + else Xfree ((char *)extension->private_data); + temp = extension->next; + Xfree ((char *)extension); + extension = temp; + } + return 0; +} diff --git a/src/FreeGC.c b/src/FreeGC.c new file mode 100644 index 00000000..9912ff6f --- /dev/null +++ b/src/FreeGC.c @@ -0,0 +1,47 @@ +/* $Xorg: FreeGC.c,v 1.4 2001/02/09 02:03:33 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XFreeGC (dpy, gc) + register Display *dpy; + GC gc; + { + register xResourceReq *req; + register _XExtension *ext; + LockDisplay(dpy); + /* call out to any extensions interested */ + for (ext = dpy->ext_procs; ext; ext = ext->next) + if (ext->free_GC) (*ext->free_GC)(dpy, gc, &ext->codes); + GetResReq (FreeGC, gc->gid, req); + UnlockDisplay(dpy); + SyncHandle(); + _XFreeExtData(gc->ext_data); + Xfree ((char *) gc); + return 1; + } + diff --git a/src/FreePix.c b/src/FreePix.c new file mode 100644 index 00000000..d90ae131 --- /dev/null +++ b/src/FreePix.c @@ -0,0 +1,42 @@ +/* $Xorg: FreePix.c,v 1.4 2001/02/09 02:03:33 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XFreePixmap(dpy, pixmap) + register Display *dpy; + Pixmap pixmap; + +{ + register xResourceReq *req; + LockDisplay(dpy); + GetResReq(FreePixmap, pixmap, req); + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} + diff --git a/src/GCMisc.c b/src/GCMisc.c new file mode 100644 index 00000000..3735f692 --- /dev/null +++ b/src/GCMisc.c @@ -0,0 +1,103 @@ +/* $Xorg: GCMisc.c,v 1.4 2001/02/09 02:03:33 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XSetArcMode (dpy, gc, arc_mode) +register Display *dpy; +register GC gc; +int arc_mode; +{ + LockDisplay(dpy); + if (gc->values.arc_mode != arc_mode) { + gc->values.arc_mode = arc_mode; + gc->dirty |= GCArcMode; + } + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} + +XSetFillRule (dpy, gc, fill_rule) +register Display *dpy; +register GC gc; +int fill_rule; +{ + LockDisplay(dpy); + if (gc->values.fill_rule != fill_rule) { + gc->values.fill_rule = fill_rule; + gc->dirty |= GCFillRule; + } + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} + +XSetFillStyle (dpy, gc, fill_style) +register Display *dpy; +register GC gc; +int fill_style; +{ + LockDisplay(dpy); + if (gc->values.fill_style != fill_style) { + gc->values.fill_style = fill_style; + gc->dirty |= GCFillStyle; + } + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} + +XSetGraphicsExposures (dpy, gc, graphics_exposures) +register Display *dpy; +register GC gc; +Bool graphics_exposures; +{ + LockDisplay(dpy); + if (gc->values.graphics_exposures != graphics_exposures) { + gc->values.graphics_exposures = graphics_exposures; + gc->dirty |= GCGraphicsExposures; + } + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} + +XSetSubwindowMode (dpy, gc, subwindow_mode) +register Display *dpy; +register GC gc; +int subwindow_mode; +{ + LockDisplay(dpy); + if (gc->values.subwindow_mode != subwindow_mode) { + gc->values.subwindow_mode = subwindow_mode; + gc->dirty |= GCSubwindowMode; + } + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} diff --git a/src/Geom.c b/src/Geom.c new file mode 100644 index 00000000..2699231d --- /dev/null +++ b/src/Geom.c @@ -0,0 +1,98 @@ +/* $Xorg: Geom.c,v 1.4 2001/02/09 02:03:33 xorgcvs Exp $ */ + +/* + +Copyright 1985, 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. + +*/ + +#include "Xlibint.h" +#include "Xutil.h" + +/* + * This routine given a user supplied positional argument and a default + * argument (fully qualified) will return the position the window should take + * returns 0 if there was some problem, else the position bitmask. + */ + +#if NeedFunctionPrototypes +int XGeometry ( + Display *dpy, /* user's display connection */ + int screen, /* screen on which to do computation */ + _Xconst char *pos, /* user provided geometry spec */ + _Xconst char *def, /* default geometry spec for window */ + unsigned int bwidth, /* border width */ + unsigned int fwidth, /* size of position units */ + unsigned int fheight, + int xadd, /* any additional interior space */ + int yadd, + register int *x, /* always set on successful RETURN */ + register int *y, /* always set on successful RETURN */ + register int *width, /* always set on successful RETURN */ + register int *height) /* always set on successful RETURN */ +#else +int XGeometry (dpy, screen, pos, def, bwidth, fwidth, fheight, xadd, yadd, x, y, width, height) + Display *dpy; /* user's display connection */ + int screen; /* screen on which to do computation */ + char *pos; /* user provided geometry spec */ + char *def; /* default geometry spec for window */ + unsigned int bwidth; /* border width */ + unsigned int fwidth, fheight; /* size of position units */ + int xadd, yadd; /* any additional interior space */ + register int *x, *y, *width, *height;/* always set on successful RETURN */ +#endif +{ + int px, py; /* returned values from parse */ + unsigned int pwidth, pheight; /* returned values from parse */ + int dx, dy; /* default values from parse */ + unsigned int dwidth, dheight; /* default values from parse */ + int pmask, dmask; /* values back from parse */ + + pmask = XParseGeometry(pos, &px, &py, &pwidth, &pheight); + dmask = XParseGeometry(def, &dx, &dy, &dwidth, &dheight); + + /* set default values */ + *x = (dmask & XNegative) ? + DisplayWidth(dpy, screen) + dx - dwidth * fwidth - + 2 * bwidth - xadd : dx; + *y = (dmask & YNegative) ? + DisplayHeight(dpy, screen) + dy - dheight * fheight - + 2 * bwidth - yadd : dy; + *width = dwidth; + *height = dheight; + + if (pmask & WidthValue) *width = pwidth; + if (pmask & HeightValue) *height = pheight; + + if (pmask & XValue) + *x = (pmask & XNegative) ? + DisplayWidth(dpy, screen) + px - *width * fwidth - + 2 * bwidth - xadd : px; + if (pmask & YValue) + *y = (pmask & YNegative) ? + DisplayHeight(dpy, screen) + py - *height * fheight - + 2 * bwidth - yadd : py; + return (pmask); +} diff --git a/src/GetAtomNm.c b/src/GetAtomNm.c new file mode 100644 index 00000000..1b11fd7a --- /dev/null +++ b/src/GetAtomNm.c @@ -0,0 +1,204 @@ +/* $Xorg: GetAtomNm.c,v 1.5 2001/02/09 02:03:33 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#define NEED_REPLIES +#include "Xlibint.h" + +extern void _XFreeAtomTable(); + +/* XXX this table def is duplicated in IntAtom.c, keep them consistent! */ + +#define TABLESIZE 64 + +typedef struct _Entry { + unsigned long sig; + Atom atom; +} EntryRec, *Entry; + +#define EntryName(e) ((char *)(e+1)) + +typedef struct _XDisplayAtoms { + Entry table[TABLESIZE]; +} AtomTable; + +static +char *_XGetAtomName(dpy, atom) + Display *dpy; + Atom atom; +{ + xResourceReq *req; + char *name; + register Entry *table; + register int idx; + register Entry e; + + if (dpy->atoms) { + table = dpy->atoms->table; + for (idx = TABLESIZE; --idx >= 0; ) { + if ((e = *table++) && (e->atom == atom)) { + idx = strlen(EntryName(e)) + 1; + if ((name = (char *)Xmalloc(idx))) + strcpy(name, EntryName(e)); + return name; + } + } + } + GetResReq(GetAtomName, atom, req); + return (char *)NULL; +} + +char *XGetAtomName(dpy, atom) + register Display *dpy; + Atom atom; +{ + xGetAtomNameReply rep; + char *name; + + LockDisplay(dpy); + if ((name = _XGetAtomName(dpy, atom))) { + UnlockDisplay(dpy); + return name; + } + if (_XReply(dpy, (xReply *)&rep, 0, xFalse) == 0) { + UnlockDisplay(dpy); + SyncHandle(); + return(NULL); + } + if ((name = (char *) Xmalloc(rep.nameLength+1))) { + _XReadPad(dpy, name, (long)rep.nameLength); + name[rep.nameLength] = '\0'; + _XUpdateAtomCache(dpy, name, atom, 0, -1, 0); + } else { + _XEatData(dpy, (unsigned long) (rep.nameLength + 3) & ~3); + name = (char *) NULL; + } + UnlockDisplay(dpy); + SyncHandle(); + return(name); +} + +typedef struct { + unsigned long start_seq; + unsigned long stop_seq; + Atom *atoms; + char **names; + int idx; + int count; + Status status; +} _XGetAtomNameState; + +static +Bool _XGetAtomNameHandler(dpy, rep, buf, len, data) + register Display *dpy; + register xReply *rep; + char *buf; + int len; + XPointer data; +{ + register _XGetAtomNameState *state; + xGetAtomNameReply replbuf; + register xGetAtomNameReply *repl; + + state = (_XGetAtomNameState *)data; + if (dpy->last_request_read < state->start_seq || + dpy->last_request_read > state->stop_seq) + return False; + while (state->idx < state->count && state->names[state->idx]) + state->idx++; + if (state->idx >= state->count) + return False; + if (rep->generic.type == X_Error) { + state->status = 0; + return False; + } + repl = (xGetAtomNameReply *) + _XGetAsyncReply(dpy, (char *)&replbuf, rep, buf, len, + (SIZEOF(xGetAtomNameReply) - SIZEOF(xReply)) >> 2, + False); + state->names[state->idx] = (char *) Xmalloc(repl->nameLength+1); + _XGetAsyncData(dpy, state->names[state->idx], buf, len, + SIZEOF(xGetAtomNameReply), repl->nameLength, + repl->length << 2); + if (state->names[state->idx]) { + state->names[state->idx][repl->nameLength] = '\0'; + _XUpdateAtomCache(dpy, state->names[state->idx], + state->atoms[state->idx], 0, -1, 0); + } else { + state->status = 0; + } + return True; +} + +Status +XGetAtomNames (dpy, atoms, count, names_return) + Display *dpy; + Atom *atoms; + int count; + char **names_return; +{ + _XAsyncHandler async; + _XGetAtomNameState async_state; + xGetAtomNameReply rep; + int i; + int missed = -1; + + LockDisplay(dpy); + async_state.start_seq = dpy->request + 1; + async_state.atoms = atoms; + async_state.names = names_return; + async_state.idx = 0; + async_state.count = count - 1; + async_state.status = 1; + async.next = dpy->async_handlers; + async.handler = _XGetAtomNameHandler; + async.data = (XPointer)&async_state; + dpy->async_handlers = &async; + for (i = 0; i < count; i++) { + if (!(names_return[i] = _XGetAtomName(dpy, atoms[i]))) { + missed = i; + async_state.stop_seq = dpy->request; + } + } + if (missed >= 0) { + if (_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + if ((names_return[missed] = (char *) Xmalloc(rep.nameLength+1))) { + _XReadPad(dpy, names_return[missed], (long)rep.nameLength); + names_return[missed][rep.nameLength] = '\0'; + _XUpdateAtomCache(dpy, names_return[missed], atoms[missed], + 0, -1, 0); + } else { + _XEatData(dpy, (unsigned long) (rep.nameLength + 3) & ~3); + async_state.status = 0; + } + } + } + DeqAsyncHandler(dpy, &async); + UnlockDisplay(dpy); + if (missed >= 0) + SyncHandle(); + return async_state.status; +} diff --git a/src/GetColor.c b/src/GetColor.c new file mode 100644 index 00000000..b469b5d4 --- /dev/null +++ b/src/GetColor.c @@ -0,0 +1,111 @@ +/* $Xorg: GetColor.c,v 1.4 2001/02/09 02:03:33 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#define NEED_REPLIES +#include <stdio.h> +#include "Xlibint.h" +#include "Xcmsint.h" + +extern void _XcmsRGB_to_XColor(); + +#if NeedFunctionPrototypes +Status XAllocNamedColor( +register Display *dpy, +Colormap cmap, +_Xconst char *colorname, /* STRING8 */ +XColor *hard_def, /* RETURN */ +XColor *exact_def) /* RETURN */ +#else +Status XAllocNamedColor(dpy, cmap, colorname, hard_def, exact_def) +register Display *dpy; +Colormap cmap; +char *colorname; /* STRING8 */ +XColor *hard_def; /* RETURN */ +XColor *exact_def; /* RETURN */ +#endif +{ + + long nbytes; + xAllocNamedColorReply rep; + xAllocNamedColorReq *req; + + XcmsCCC ccc; + XcmsColor cmsColor_exact; + Status ret; + + /* + * Let's Attempt to use Xcms and i18n approach to Parse Color + */ + /* copy string to allow overwrite by _XcmsResolveColorString() */ + if ((ccc = XcmsCCCOfColormap(dpy, cmap)) != (XcmsCCC)NULL) { + if (_XcmsResolveColorString(ccc, &colorname, &cmsColor_exact, + XcmsRGBFormat) >= XcmsSuccess) { + _XcmsRGB_to_XColor(&cmsColor_exact, exact_def, 1); + memcpy((char *)hard_def, (char *)exact_def, sizeof(XColor)); + ret = XAllocColor(dpy, cmap, hard_def); + exact_def->pixel = hard_def->pixel; + return(ret); + } + /* + * Otherwise we failed; or colorname was changed with yet another + * name. Thus pass name to the X Server. + */ + } + + /* + * Xcms and i18n approach failed. + */ + LockDisplay(dpy); + GetReq(AllocNamedColor, req); + + req->cmap = cmap; + nbytes = req->nbytes = strlen(colorname); + req->length += (nbytes + 3) >> 2; /* round up to mult of 4 */ + + _XSend(dpy, colorname, nbytes); + /* _XSend is more efficient that Data, since _XReply follows */ + + if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) { + UnlockDisplay(dpy); + SyncHandle(); + return (0); + } + + exact_def->red = rep.exactRed; + exact_def->green = rep.exactGreen; + exact_def->blue = rep.exactBlue; + + hard_def->red = rep.screenRed; + hard_def->green = rep.screenGreen; + hard_def->blue = rep.screenBlue; + + exact_def->pixel = hard_def->pixel = rep.pixel; + + UnlockDisplay(dpy); + SyncHandle(); + return (1); +} diff --git a/src/GetDflt.c b/src/GetDflt.c new file mode 100644 index 00000000..6e05abd4 --- /dev/null +++ b/src/GetDflt.c @@ -0,0 +1,247 @@ +/* $Xorg: GetDflt.c,v 1.6 2001/02/09 02:03:33 xorgcvs Exp $ */ + +/*********************************************************** + +Copyright 1987, 1988, 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, 1988 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. + +******************************************************************/ + +#include "Xlibint.h" +#include <X11/Xos.h> +#include <X11/Xresource.h> + +#ifndef X_NOT_POSIX +#ifdef _POSIX_SOURCE +#include <limits.h> +#else +#define _POSIX_SOURCE +#include <limits.h> +#undef _POSIX_SOURCE +#endif +#endif +#ifndef PATH_MAX +#ifdef WIN32 +#define PATH_MAX 512 +#else +#include <sys/param.h> +#endif +#ifndef PATH_MAX +#ifdef MAXPATHLEN +#define PATH_MAX MAXPATHLEN +#else +#define PATH_MAX 1024 +#endif +#endif +#endif + +#ifdef XTHREADS +#include <X11/Xthreads.h> +#endif +#ifndef WIN32 +#define X_INCLUDE_PWD_H +#define XOS_USE_XLIB_LOCKING +#include <X11/Xos_r.h> +#endif +#include <stdio.h> +#include <ctype.h> + +#ifdef X_NOT_STDC_ENV +extern char *getenv(); +#endif + +/*ARGSUSED*/ +static char *GetHomeDir (dest, len) + char *dest; + int len; +{ +#ifdef WIN32 + register char *ptr1; + register char *ptr2; + int len1 = 0, len2 = 0; + + if (ptr1 = getenv("HOME")) { /* old, deprecated */ + len1 = strlen (ptr1); + } else if ((ptr1 = getenv("HOMEDRIVE")) && (ptr2 = getenv("HOMEDIR"))) { + len1 = strlen (ptr1); + len2 = strlen (ptr2); + } else if (ptr2 = getenv("USERNAME")) { + len1 = strlen (ptr1 = "/users/"); + len2 = strlen (ptr2); + } + if ((len1 + len2 + 1) < len) + sprintf (dest, "%s%s", ptr1, (ptr2) ? ptr2 : ""); + else + *dest = '\0'; +#else + _Xgetpwparams pwparams; + struct passwd *pw; + register char *ptr; + + if (len <= 0 || dest == NULL) + return NULL; + + if ((ptr = getenv("HOME"))) { + (void) strncpy(dest, ptr, len); + dest[len-1] = '\0'; + } else { + if ((ptr = getenv("USER"))) + pw = _XGetpwnam(ptr,pwparams); + else + pw = _XGetpwuid(getuid(),pwparams); + if (pw != NULL) { + (void) strncpy(dest, pw->pw_dir, len); + dest[len-1] = '\0'; + } else + *dest = '\0'; + } +#endif + return dest; +} + + +static XrmDatabase InitDefaults (dpy) + Display *dpy; /* display for defaults.... */ +{ + XrmDatabase userdb; + XrmDatabase xdb; + char fname[PATH_MAX]; /* longer than any conceivable size */ + char *xenv; + + XrmInitialize(); + + /* + * See lib/Xt/Initialize.c + * + * First, get the defaults from the server; if none, then load from + * ~/.Xdefaults. Next, if there is an XENVIRONMENT environment variable, + * then load that file. + */ + + if (dpy->xdefaults == NULL) { + char *slashDotXdefaults = "/.Xdefaults"; + + (void) GetHomeDir (fname, PATH_MAX - strlen (slashDotXdefaults) - 1); + (void) strcat (fname, slashDotXdefaults); + xdb = XrmGetFileDatabase (fname); + } else { + xdb = XrmGetStringDatabase(dpy->xdefaults); + } + + if (!(xenv = getenv ("XENVIRONMENT"))) { + char *slashDotXdefaultsDash = "/.Xdefaults-"; + int len; + + (void) GetHomeDir (fname, PATH_MAX - strlen (slashDotXdefaultsDash) - 1); + (void) strcat (fname, slashDotXdefaultsDash); + len = strlen (fname); + (void) _XGetHostname (fname+len, PATH_MAX-len); + xenv = fname; + } + userdb = XrmGetFileDatabase (xenv); + XrmMergeDatabases (userdb, &xdb); + return (xdb); + +#ifdef old + if (fname[0] != '\0') userdb = XrmGetFileDatabase(fname); + xdb = XrmGetStringDatabase(dpy->xdefaults); + XrmMergeDatabases(userdb, &xdb); + return xdb; +#endif +} + +#if NeedFunctionPrototypes +char *XGetDefault( + Display *dpy, /* display for defaults.... */ + char _Xconst *prog, /* name of program for option */ + register _Xconst char *name) /* name of option program wants */ +#else +char *XGetDefault(dpy, prog, name) + Display *dpy; /* display for defaults.... */ + char *prog; /* name of program for option */ + register char *name; /* name of option program wants */ +#endif +{ /* to get, for example, "font" */ + XrmName names[3]; + XrmClass classes[3]; + XrmRepresentation fromType; + XrmValue result; + char *progname; +#ifdef WIN32 + char *progname2; +#endif + + /* + * strip path off of program name (XXX - this is OS specific) + */ + progname = strrchr (prog, '/'); +#ifdef WIN32 + progname2 = strrchr (prog, '\\'); + if (progname2 && (!progname || progname < progname2)) + progname = progname2; +#endif + if (progname) + progname++; + else + progname = (char *)prog; + + /* + * see if database has ever been initialized. Lookups can be done + * without locks held. + */ + LockDisplay(dpy); + if (dpy->db == NULL) { + dpy->db = InitDefaults(dpy); + } + UnlockDisplay(dpy); + + names[0] = XrmStringToName(progname); + names[1] = XrmStringToName(name); + names[2] = NULLQUARK; + classes[0] = XrmStringToClass("Program"); + classes[1] = XrmStringToClass("Name"); + classes[2] = NULLQUARK; + (void)XrmQGetResource(dpy->db, names, classes, &fromType, &result); + return (result.addr); +} + diff --git a/src/GetFPath.c b/src/GetFPath.c new file mode 100644 index 00000000..69dd809c --- /dev/null +++ b/src/GetFPath.c @@ -0,0 +1,90 @@ +/* $Xorg: GetFPath.c,v 1.4 2001/02/09 02:03:33 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#define NEED_REPLIES +#include "Xlibint.h" + +char **XGetFontPath(dpy, npaths) +register Display *dpy; +int *npaths; /* RETURN */ +{ + xGetFontPathReply rep; + register long nbytes; + char **flist; + char *ch; + register unsigned i; + register int length; + register xReq *req; + + LockDisplay(dpy); + GetEmptyReq (GetFontPath, req); + (void) _XReply (dpy, (xReply *) &rep, 0, xFalse); + + if (rep.nPaths) { + flist = (char **) + Xmalloc((unsigned) rep.nPaths * sizeof (char *)); + nbytes = (long)rep.length << 2; + ch = (char *) Xmalloc ((unsigned) (nbytes + 1)); + /* +1 to leave room for last null-terminator */ + + if ((! flist) || (! ch)) { + if (flist) Xfree((char *) flist); + if (ch) Xfree(ch); + _XEatData(dpy, (unsigned long) nbytes); + UnlockDisplay(dpy); + SyncHandle(); + return (char **) NULL; + } + + _XReadPad (dpy, ch, nbytes); + /* + * unpack into null terminated strings. + */ + length = *ch; + for (i = 0; i < rep.nPaths; i++) { + flist[i] = ch+1; /* skip over length */ + ch += length + 1; /* find next length ... */ + length = *ch; + *ch = '\0'; /* and replace with null-termination */ + } + } + else flist = NULL; + *npaths = rep.nPaths; + UnlockDisplay(dpy); + SyncHandle(); + return (flist); +} + +XFreeFontPath (list) +char **list; +{ + if (list != NULL) { + Xfree (list[0]-1); + Xfree ((char *)list); + } + return 1; +} diff --git a/src/GetFProp.c b/src/GetFProp.c new file mode 100644 index 00000000..f588c2f0 --- /dev/null +++ b/src/GetFProp.c @@ -0,0 +1,53 @@ +/* $Xorg: GetFProp.c,v 1.4 2001/02/09 02:03:33 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +Bool XGetFontProperty (fs, name, valuePtr) + XFontStruct *fs; + register Atom name; + unsigned long *valuePtr; + { + /* XXX this is a simple linear search for now. If the + protocol is changed to sort the property list, this should + become a binary search. */ + register XFontProp *prop = fs->properties; + register XFontProp *last = prop + fs->n_properties; + while (prop != last) { + if (prop->name == name) { + *valuePtr = prop->card32; + return (1); + } + prop++; + } + return (0); + } + + + + + diff --git a/src/GetGCVals.c b/src/GetGCVals.c new file mode 100644 index 00000000..e8875869 --- /dev/null +++ b/src/GetGCVals.c @@ -0,0 +1,126 @@ +/* $Xorg: GetGCVals.c,v 1.4 2001/02/09 02:03:33 xorgcvs Exp $ */ + +/* + +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. + +*/ + +#include "Xlibint.h" + +/* + * All gc fields except GCClipMask and GCDashList + */ +#define ValidGCValuesBits (GCFunction | GCPlaneMask | GCForeground | \ + GCBackground | GCLineWidth | GCLineStyle | \ + GCCapStyle | GCJoinStyle | GCFillStyle | \ + GCFillRule | GCTile | GCStipple | \ + GCTileStipXOrigin | GCTileStipYOrigin | \ + GCFont | GCSubwindowMode | GCGraphicsExposures | \ + GCClipXOrigin | GCClipYOrigin | GCDashOffset | \ + GCArcMode) + +/*ARGSUSED*/ +Status XGetGCValues (dpy, gc, valuemask, values) + Display *dpy; + GC gc; + unsigned long valuemask; + XGCValues *values; +{ + if (valuemask == ValidGCValuesBits) { + char dashes = values->dashes; + Pixmap clip_mask = values->clip_mask; + *values = gc->values; + values->dashes = dashes; + values->clip_mask = clip_mask; + return True; + } + + if (valuemask & ~ValidGCValuesBits) return False; + + if (valuemask & GCFunction) + values->function = gc->values.function; + + if (valuemask & GCPlaneMask) + values->plane_mask = gc->values.plane_mask; + + if (valuemask & GCForeground) + values->foreground = gc->values.foreground; + + if (valuemask & GCBackground) + values->background = gc->values.background; + + if (valuemask & GCLineWidth) + values->line_width = gc->values.line_width; + + if (valuemask & GCLineStyle) + values->line_style = gc->values.line_style; + + if (valuemask & GCCapStyle) + values->cap_style = gc->values.cap_style; + + if (valuemask & GCJoinStyle) + values->join_style = gc->values.join_style; + + if (valuemask & GCFillStyle) + values->fill_style = gc->values.fill_style; + + if (valuemask & GCFillRule) + values->fill_rule = gc->values.fill_rule; + + if (valuemask & GCTile) + values->tile = gc->values.tile; + + if (valuemask & GCStipple) + values->stipple = gc->values.stipple; + + if (valuemask & GCTileStipXOrigin) + values->ts_x_origin = gc->values.ts_x_origin; + + if (valuemask & GCTileStipYOrigin) + values->ts_y_origin = gc->values.ts_y_origin; + + if (valuemask & GCFont) + values->font = gc->values.font; + + if (valuemask & GCSubwindowMode) + values->subwindow_mode = gc->values.subwindow_mode; + + if (valuemask & GCGraphicsExposures) + values->graphics_exposures = gc->values.graphics_exposures; + + if (valuemask & GCClipXOrigin) + values->clip_x_origin = gc->values.clip_x_origin; + + if (valuemask & GCClipYOrigin) + values->clip_y_origin = gc->values.clip_y_origin; + + if (valuemask & GCDashOffset) + + values->dash_offset = gc->values.dash_offset; + + if (valuemask & GCArcMode) + values->arc_mode = gc->values.arc_mode; + + return True; +} diff --git a/src/GetGeom.c b/src/GetGeom.c new file mode 100644 index 00000000..367153f4 --- /dev/null +++ b/src/GetGeom.c @@ -0,0 +1,58 @@ +/* $Xorg: GetGeom.c,v 1.4 2001/02/09 02:03:33 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#define NEED_REPLIES +#include "Xlibint.h" + +Status XGetGeometry (dpy, d, root, x, y, width, height, borderWidth, depth) + register Display *dpy; + Drawable d; + Window *root; /* RETURN */ + int *x, *y; /* RETURN */ + unsigned int *width, *height, *borderWidth, *depth; /* RETURN */ +{ + xGetGeometryReply rep; + register xResourceReq *req; + LockDisplay(dpy); + GetResReq(GetGeometry, d, req); + if (!_XReply (dpy, (xReply *)&rep, 0, xTrue)) { + UnlockDisplay(dpy); + SyncHandle(); + return (0); + } + *root = rep.root; + *x = cvtINT16toInt (rep.x); + *y = cvtINT16toInt (rep.y); + *width = rep.width; + *height = rep.height; + *borderWidth = rep.borderWidth; + *depth = rep.depth; + UnlockDisplay(dpy); + SyncHandle(); + return (1); +} + diff --git a/src/GetHColor.c b/src/GetHColor.c new file mode 100644 index 00000000..33e6ad59 --- /dev/null +++ b/src/GetHColor.c @@ -0,0 +1,57 @@ +/* $Xorg: GetHColor.c,v 1.4 2001/02/09 02:03:33 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#define NEED_REPLIES +#include "Xlibint.h" + +Status XAllocColor(dpy, cmap, def) +register Display *dpy; +Colormap cmap; +XColor *def; +{ + Status status; + xAllocColorReply rep; + register xAllocColorReq *req; + LockDisplay(dpy); + GetReq(AllocColor, req); + + req->cmap = cmap; + req->red = def->red; + req->green = def->green; + req->blue = def->blue; + + status = _XReply(dpy, (xReply *) &rep, 0, xTrue); + if (status) { + def->pixel = rep.pixel; + def->red = rep.red; + def->green = rep.green; + def->blue = rep.blue; + } + UnlockDisplay(dpy); + SyncHandle(); + return(status); +} diff --git a/src/GetHints.c b/src/GetHints.c new file mode 100644 index 00000000..7958fd1f --- /dev/null +++ b/src/GetHints.c @@ -0,0 +1,337 @@ +/* $Xorg: GetHints.c,v 1.5 2001/02/09 02:03:33 xorgcvs Exp $ */ + +/*********************************************************** + +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. + +******************************************************************/ + +#include <X11/Xlibint.h> +#include <X11/Xos.h> +#include <X11/Xutil.h> +#include "Xatomtype.h" +#include <X11/Xatom.h> +#include <stdio.h> + +Status XGetSizeHints (dpy, w, hints, property) + Display *dpy; + Window w; + XSizeHints *hints; + Atom property; +{ + xPropSizeHints *prop = NULL; + Atom actual_type; + int actual_format; + unsigned long leftover; + unsigned long nitems; + if (XGetWindowProperty(dpy, w, property, 0L, + (long) OldNumPropSizeElements, + False, XA_WM_SIZE_HINTS, &actual_type, &actual_format, + &nitems, &leftover, (unsigned char **)&prop) + != Success) return (0); + + if ((actual_type != XA_WM_SIZE_HINTS) || + (nitems < OldNumPropSizeElements) || (actual_format != 32)) { + if (prop != NULL) Xfree ((char *)prop); + return(0); + } + hints->flags = (prop->flags & (USPosition|USSize|PAllHints)); + hints->x = cvtINT32toInt (prop->x); + hints->y = cvtINT32toInt (prop->y); + hints->width = cvtINT32toInt (prop->width); + hints->height = cvtINT32toInt (prop->height); + hints->min_width = cvtINT32toInt (prop->minWidth); + hints->min_height = cvtINT32toInt (prop->minHeight); + hints->max_width = cvtINT32toInt (prop->maxWidth); + hints->max_height = cvtINT32toInt (prop->maxHeight); + hints->width_inc = cvtINT32toInt (prop->widthInc); + hints->height_inc = cvtINT32toInt (prop->heightInc); + hints->min_aspect.x = cvtINT32toInt (prop->minAspectX); + hints->min_aspect.y = cvtINT32toInt (prop->minAspectY); + hints->max_aspect.x = cvtINT32toInt (prop->maxAspectX); + hints->max_aspect.y = cvtINT32toInt (prop->maxAspectY); + Xfree((char *)prop); + return(1); +} + +/* + * must return a pointer to the hint, in malloc'd memory, or routine is not + * extensible; any use of the caller's memory would cause things to be stepped + * on. + */ + +XWMHints *XGetWMHints (dpy, w) + Display *dpy; + Window w; +{ + xPropWMHints *prop = NULL; + register XWMHints *hints; + Atom actual_type; + int actual_format; + unsigned long leftover; + unsigned long nitems; + if (XGetWindowProperty(dpy, w, XA_WM_HINTS, + 0L, (long)NumPropWMHintsElements, + False, XA_WM_HINTS, &actual_type, &actual_format, + &nitems, &leftover, (unsigned char **)&prop) + != Success) return (NULL); + + /* If the property is undefined on the window, return null pointer. */ + /* pre-R3 bogusly truncated window_group, don't fail on them */ + + if ((actual_type != XA_WM_HINTS) || + (nitems < (NumPropWMHintsElements - 1)) || (actual_format != 32)) { + if (prop != NULL) Xfree ((char *)prop); + return(NULL); + } + /* static copies not allowed in library, due to reentrancy constraint*/ + if ((hints = (XWMHints *) Xcalloc (1, (unsigned) sizeof(XWMHints)))) { + hints->flags = prop->flags; + hints->input = (prop->input ? True : False); + hints->initial_state = cvtINT32toInt (prop->initialState); + hints->icon_pixmap = prop->iconPixmap; + hints->icon_window = prop->iconWindow; + hints->icon_x = cvtINT32toInt (prop->iconX); + hints->icon_y = cvtINT32toInt (prop->iconY); + hints->icon_mask = prop->iconMask; + if (nitems >= NumPropWMHintsElements) + hints->window_group = prop->windowGroup; + else + hints->window_group = 0; + } + Xfree ((char *)prop); + return(hints); +} + +Status +XGetZoomHints (dpy, w, zhints) + Display *dpy; + Window w; + XSizeHints *zhints; +{ + return (XGetSizeHints(dpy, w, zhints, XA_WM_ZOOM_HINTS)); +} + +Status +XGetNormalHints (dpy, w, hints) + Display *dpy; + Window w; + XSizeHints *hints; +{ + return (XGetSizeHints(dpy, w, hints, XA_WM_NORMAL_HINTS)); +} + + +/* + * XGetIconSizes reads the property + * ICONSIZE_ATOM type: ICONSIZE_ATOM format: 32 + */ + +Status XGetIconSizes (dpy, w, size_list, count) + Display *dpy; + Window w; /* typically, root */ + XIconSize **size_list; /* RETURN */ + int *count; /* RETURN number of items on the list */ +{ + xPropIconSize *prop = NULL; + register xPropIconSize *pp; + register XIconSize *hp, *hints; + Atom actual_type; + int actual_format; + unsigned long leftover; + unsigned long nitems; + register int i; + + if (XGetWindowProperty(dpy, w, XA_WM_ICON_SIZE, 0L, 60L, + False, XA_WM_ICON_SIZE, &actual_type, &actual_format, + &nitems, &leftover, (unsigned char **)&prop) + != Success) return (0); + + pp = prop; + + if ((actual_type != XA_WM_ICON_SIZE) || + (nitems < NumPropIconSizeElements) || + (nitems % NumPropIconSizeElements != 0) || + (actual_format != 32)) { + if (prop != NULL) Xfree ((char *)prop); + return(0); + } + + /* static copies not allowed in library, due to reentrancy constraint*/ + + nitems /= NumPropIconSizeElements; + if (! (hp = hints = (XIconSize *) + Xcalloc ((unsigned) nitems, (unsigned) sizeof(XIconSize)))) { + if (prop) Xfree ((char *) prop); + return 0; + } + + /* march down array putting things into native form */ + for (i = 0; i < nitems; i++) { + hp->min_width = cvtINT32toInt (pp->minWidth); + hp->min_height = cvtINT32toInt (pp->minHeight); + hp->max_width = cvtINT32toInt (pp->maxWidth); + hp->max_height = cvtINT32toInt (pp->maxHeight); + hp->width_inc = cvtINT32toInt (pp->widthInc); + hp->height_inc = cvtINT32toInt (pp->heightInc); + hp += 1; + pp += 1; + } + *count = nitems; + *size_list = hints; + Xfree ((char *)prop); + return(1); +} + + +Status XGetCommand (dpy, w, argvp, argcp) + Display *dpy; + Window w; + char ***argvp; + int *argcp; +{ + XTextProperty tp; + int argc; + char **argv; + + if (!XGetTextProperty (dpy, w, &tp, XA_WM_COMMAND)) return 0; + + if (tp.encoding != XA_STRING || tp.format != 8) { + if (tp.value) Xfree ((char *) tp.value); + return 0; + } + + + /* + * ignore final <NUL> if present since UNIX WM_COMMAND is nul-terminated + */ + if (tp.nitems && (tp.value[tp.nitems - 1] == '\0')) tp.nitems--; + + + /* + * create a string list and return if successful + */ + if (!XTextPropertyToStringList (&tp, &argv, &argc)) { + if (tp.value) Xfree ((char *) tp.value); + return (0); + } + + if (tp.value) Xfree ((char *) tp.value); + *argvp = argv; + *argcp = argc; + return 1; +} + + +Status +XGetTransientForHint(dpy, w, propWindow) + Display *dpy; + Window w; + Window *propWindow; +{ + Atom actual_type; + int actual_format; + unsigned long nitems; + unsigned long leftover; + Window *data = NULL; + if (XGetWindowProperty(dpy, w, XA_WM_TRANSIENT_FOR, 0L, 1L, False, + XA_WINDOW, + &actual_type, + &actual_format, &nitems, &leftover, (unsigned char **) &data) + != Success) { + *propWindow = None; + return (0); + } + if ( (actual_type == XA_WINDOW) && (actual_format == 32) && + (nitems != 0) ) { + *propWindow = *data; + Xfree( (char *) data); + return (1); + } + *propWindow = None; + if (data) Xfree( (char *) data); + return(0); +} + +Status +XGetClassHint(dpy, w, classhint) + Display *dpy; + Window w; + XClassHint *classhint; /* RETURN */ +{ + int len_name, len_class; + + Atom actual_type; + int actual_format; + unsigned long nitems; + unsigned long leftover; + unsigned char *data = NULL; + if (XGetWindowProperty(dpy, w, XA_WM_CLASS, 0L, (long)BUFSIZ, False, + XA_STRING, + &actual_type, + &actual_format, &nitems, &leftover, &data) != Success) + return (0); + + if ( (actual_type == XA_STRING) && (actual_format == 8) ) { + len_name = strlen((char *) data); + if (! (classhint->res_name = Xmalloc((unsigned) (len_name+1)))) { + Xfree((char *) data); + return (0); + } + strcpy(classhint->res_name, (char *) data); + if (len_name == nitems) len_name--; + len_class = strlen((char *) (data+len_name+1)); + if (! (classhint->res_class = Xmalloc((unsigned) (len_class+1)))) { + Xfree(classhint->res_name); + classhint->res_name = (char *) NULL; + Xfree((char *) data); + return (0); + } + strcpy(classhint->res_class, (char *) (data+len_name+1)); + Xfree( (char *) data); + return(1); + } + if (data) Xfree( (char *) data); + return(0); +} diff --git a/src/GetIFocus.c b/src/GetIFocus.c new file mode 100644 index 00000000..7e2ca86c --- /dev/null +++ b/src/GetIFocus.c @@ -0,0 +1,47 @@ +/* $Xorg: GetIFocus.c,v 1.4 2001/02/09 02:03:33 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#define NEED_REPLIES +#include "Xlibint.h" + +XGetInputFocus(dpy, focus, revert_to) + register Display *dpy; + Window *focus; + int *revert_to; +{ + xGetInputFocusReply rep; + register xReq *req; + LockDisplay(dpy); + GetEmptyReq(GetInputFocus, req); + (void) _XReply (dpy, (xReply *)&rep, 0, xTrue); + *focus = rep.focus; + *revert_to = rep.revertTo; + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} + diff --git a/src/GetImage.c b/src/GetImage.c new file mode 100644 index 00000000..ab665d81 --- /dev/null +++ b/src/GetImage.c @@ -0,0 +1,122 @@ +/* $Xorg: GetImage.c,v 1.4 2001/02/09 02:03:33 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#define NEED_REPLIES +#include "Xlibint.h" +#include <X11/Xutil.h> /* for XDestroyImage */ + +#define ROUNDUP(nbytes, pad) (((((nbytes) - 1) + (pad)) / (pad)) * (pad)) + +static unsigned int Ones(mask) /* HACKMEM 169 */ + unsigned long mask; +{ + register unsigned long y; + + y = (mask >> 1) &033333333333; + y = mask - y - ((y >>1) & 033333333333); + return ((unsigned int) (((y + (y >> 3)) & 030707070707) % 077)); +} + +XImage *XGetImage (dpy, d, x, y, width, height, plane_mask, format) + register Display *dpy; + Drawable d; + int x, y; + unsigned int width, height; + unsigned long plane_mask; + int format; /* either XYPixmap or ZPixmap */ +{ + xGetImageReply rep; + register xGetImageReq *req; + char *data; + long nbytes; + XImage *image; + LockDisplay(dpy); + GetReq (GetImage, req); + /* + * first set up the standard stuff in the request + */ + req->drawable = d; + req->x = x; + req->y = y; + req->width = width; + req->height = height; + req->planeMask = plane_mask; + req->format = format; + + if (_XReply (dpy, (xReply *) &rep, 0, xFalse) == 0 || + rep.length == 0) { + UnlockDisplay(dpy); + SyncHandle(); + return (XImage *)NULL; + } + + nbytes = (long)rep.length << 2; + data = (char *) Xmalloc((unsigned) nbytes); + if (! data) { + _XEatData(dpy, (unsigned long) nbytes); + UnlockDisplay(dpy); + SyncHandle(); + return (XImage *) NULL; + } + _XReadPad (dpy, data, nbytes); + if (format == XYPixmap) + image = XCreateImage(dpy, _XVIDtoVisual(dpy, rep.visual), + Ones (plane_mask & + (((unsigned long)0xFFFFFFFF) >> (32 - rep.depth))), + format, 0, data, width, height, dpy->bitmap_pad, 0); + else /* format == ZPixmap */ + image = XCreateImage (dpy, _XVIDtoVisual(dpy, rep.visual), + rep.depth, ZPixmap, 0, data, width, height, + _XGetScanlinePad(dpy, (int) rep.depth), 0); + + if (!image) + Xfree(data); + UnlockDisplay(dpy); + SyncHandle(); + return (image); +} + +XImage *XGetSubImage(dpy, d, x, y, width, height, plane_mask, format, + dest_image, dest_x, dest_y) + register Display *dpy; + Drawable d; + int x, y; + unsigned int width, height; + unsigned long plane_mask; + int format; /* either XYPixmap or ZPixmap */ + XImage *dest_image; + int dest_x, dest_y; +{ + XImage *temp_image; + temp_image = XGetImage(dpy, d, x, y, width, height, + plane_mask, format); + if (!temp_image) + return (XImage *)NULL; + _XSetImage(temp_image, dest_image, dest_x, dest_y); + XDestroyImage(temp_image); + return (dest_image); +} diff --git a/src/GetKCnt.c b/src/GetKCnt.c new file mode 100644 index 00000000..d8fa69c9 --- /dev/null +++ b/src/GetKCnt.c @@ -0,0 +1,53 @@ +/* $Xorg: GetKCnt.c,v 1.4 2001/02/09 02:03:33 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#define NEED_REPLIES +#include "Xlibint.h" + +XGetKeyboardControl (dpy, state) + register Display *dpy; + register XKeyboardState *state; + { + xGetKeyboardControlReply rep; + register xReq *req; + LockDisplay(dpy); + GetEmptyReq (GetKeyboardControl, req); + (void) _XReply (dpy, (xReply *) &rep, + (SIZEOF(xGetKeyboardControlReply) - SIZEOF(xReply)) >> 2, xTrue); + + state->key_click_percent = rep.keyClickPercent; + state->bell_percent = rep.bellPercent; + state->bell_pitch = rep.bellPitch; + state->bell_duration = rep.bellDuration; + state->led_mask = rep.ledMask; + state->global_auto_repeat = rep.globalAutoRepeat; + memcpy (state->auto_repeats, rep.map, sizeof state->auto_repeats); + UnlockDisplay(dpy); + SyncHandle(); + return 1; + } + diff --git a/src/GetMoEv.c b/src/GetMoEv.c new file mode 100644 index 00000000..1bead38a --- /dev/null +++ b/src/GetMoEv.c @@ -0,0 +1,83 @@ +/* $Xorg: GetMoEv.c,v 1.4 2001/02/09 02:03:33 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#define NEED_REPLIES +#include "Xlibint.h" + +XTimeCoord *XGetMotionEvents(dpy, w, start, stop, nEvents) + register Display *dpy; + Time start, stop; + Window w; + int *nEvents; /* RETURN */ +{ + xGetMotionEventsReply rep; + register xGetMotionEventsReq *req; + XTimeCoord *tc = NULL; + long nbytes; + LockDisplay(dpy); + GetReq(GetMotionEvents, req); + req->window = w; +/* XXX is this right for all machines? */ + req->start = start; + req->stop = stop; + if (!_XReply (dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return (NULL); + } + + if (rep.nEvents) { + if (! (tc = (XTimeCoord *) + Xmalloc( (unsigned) + (nbytes = (long) rep.nEvents * sizeof(XTimeCoord))))) { + _XEatData (dpy, (unsigned long) nbytes); + UnlockDisplay(dpy); + SyncHandle(); + return (NULL); + } + } + + *nEvents = rep.nEvents; + nbytes = SIZEOF (xTimecoord); + { + register XTimeCoord *tcptr; + register int i; + xTimecoord xtc; + + for (i = rep.nEvents, tcptr = tc; i > 0; i--, tcptr++) { + _XRead (dpy, (char *) &xtc, nbytes); + tcptr->time = xtc.time; + tcptr->x = cvtINT16toShort (xtc.x); + tcptr->y = cvtINT16toShort (xtc.y); + } + } + + UnlockDisplay(dpy); + SyncHandle(); + return (tc); +} + diff --git a/src/GetNrmHint.c b/src/GetNrmHint.c new file mode 100644 index 00000000..741d1531 --- /dev/null +++ b/src/GetNrmHint.c @@ -0,0 +1,125 @@ +/* $Xorg: GetNrmHint.c,v 1.4 2001/02/09 02:03:33 xorgcvs Exp $ */ +/*********************************************************** +Copyright 1988 by Wyse Technology, Inc., San Jose, Ca, +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 Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL AND WYSE DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO +EVENT SHALL DIGITAL OR WYSE 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. + +******************************************************************/ + +/* + +Copyright 1987, 1988, 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. + +*/ + + +#include <X11/Xlibint.h> +#include <X11/Xatom.h> +#include "Xatomtype.h" +#include <X11/Xutil.h> +#include <stdio.h> + +Status XGetWMSizeHints (dpy, w, hints, supplied, property) + Display *dpy; + Window w; + XSizeHints *hints; + long *supplied; + Atom property; +{ + xPropSizeHints *prop = NULL; + Atom actual_type; + int actual_format; + unsigned long leftover; + unsigned long nitems; + + if (XGetWindowProperty (dpy, w, property, 0L, + (long)NumPropSizeElements, + False, XA_WM_SIZE_HINTS, &actual_type, + &actual_format, &nitems, &leftover, + (unsigned char **)&prop) + != Success) + return False; + + if ((actual_type != XA_WM_SIZE_HINTS) || + (nitems < OldNumPropSizeElements) || (actual_format != 32)) { + if (prop != NULL) Xfree ((char *)prop); + return False; + } + + hints->flags = prop->flags; + /* XSizeHints misdeclares these as int instead of long */ + hints->x = cvtINT32toInt (prop->x); + hints->y = cvtINT32toInt (prop->y); + hints->width = cvtINT32toInt (prop->width); + hints->height = cvtINT32toInt (prop->height); + hints->min_width = cvtINT32toInt (prop->minWidth); + hints->min_height = cvtINT32toInt (prop->minHeight); + hints->max_width = cvtINT32toInt (prop->maxWidth); + hints->max_height = cvtINT32toInt (prop->maxHeight); + hints->width_inc = cvtINT32toInt (prop->widthInc); + hints->height_inc = cvtINT32toInt (prop->heightInc); + hints->min_aspect.x = cvtINT32toInt (prop->minAspectX); + hints->min_aspect.y = cvtINT32toInt (prop->minAspectY); + hints->max_aspect.x = cvtINT32toInt (prop->maxAspectX); + hints->max_aspect.y = cvtINT32toInt (prop->maxAspectY); + + *supplied = (USPosition | USSize | PAllHints); + if (nitems >= NumPropSizeElements) { + hints->base_width= cvtINT32toInt (prop->baseWidth); + hints->base_height= cvtINT32toInt (prop->baseHeight); + hints->win_gravity= cvtINT32toInt (prop->winGravity); + *supplied |= (PBaseSize | PWinGravity); + } + hints->flags &= (*supplied); /* get rid of unwanted bits */ + Xfree((char *)prop); + return True; +} + + +Status XGetWMNormalHints (dpy, w, hints, supplied) + Display *dpy; + Window w; + XSizeHints *hints; + long *supplied; +{ + return (XGetWMSizeHints (dpy, w, hints, supplied, XA_WM_NORMAL_HINTS)); +} diff --git a/src/GetPCnt.c b/src/GetPCnt.c new file mode 100644 index 00000000..54b84270 --- /dev/null +++ b/src/GetPCnt.c @@ -0,0 +1,49 @@ +/* $Xorg: GetPCnt.c,v 1.4 2001/02/09 02:03:33 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#define NEED_REPLIES +#include "Xlibint.h" + +XGetPointerControl(dpy, accel_numer, accel_denom, threshold) + register Display *dpy; + /* the following are return only vars */ + int *accel_numer, *accel_denom; + int *threshold; +{ + xGetPointerControlReply rep; + xReq *req; + LockDisplay(dpy); + GetEmptyReq(GetPointerControl, req); + (void) _XReply (dpy, (xReply *)&rep, 0, xTrue); + *accel_numer = rep.accelNumerator; + *accel_denom = rep.accelDenominator; + *threshold = rep.threshold; + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} + diff --git a/src/GetPntMap.c b/src/GetPntMap.c new file mode 100644 index 00000000..9af3a57c --- /dev/null +++ b/src/GetPntMap.c @@ -0,0 +1,127 @@ +/* $Xorg: GetPntMap.c,v 1.4 2001/02/09 02:03:33 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#define NEED_REPLIES +#include "Xlibint.h" + +#ifdef MIN /* some systems define this in <sys/param.h> */ +#undef MIN +#endif +#define MIN(a, b) ((a) < (b) ? (a) : (b)) + +int XGetPointerMapping (dpy, map, nmaps) + register Display *dpy; + unsigned char *map; /* RETURN */ + int nmaps; + +{ + unsigned char mapping[256]; /* known fixed size */ + long nbytes, remainder = 0; + xGetPointerMappingReply rep; + register xReq *req; + + LockDisplay(dpy); + GetEmptyReq(GetPointerMapping, req); + if (! _XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return 0; + } + + nbytes = (long)rep.length << 2; + + if (nbytes > sizeof mapping) { + remainder = nbytes - sizeof mapping; + nbytes = sizeof mapping; + } + _XRead (dpy, (char *)mapping, nbytes); + /* don't return more data than the user asked for. */ + if (rep.nElts) { + memcpy ((char *) map, (char *) mapping, + MIN((int)rep.nElts, nmaps) ); + } + + if (remainder) + _XEatData(dpy, (unsigned long)remainder); + + UnlockDisplay(dpy); + SyncHandle(); + return ((int) rep.nElts); +} + +#if NeedFunctionPrototypes +KeySym *XGetKeyboardMapping (Display *dpy, +#if NeedWidePrototypes + unsigned int first_keycode, +#else + KeyCode first_keycode, +#endif + int count, + int *keysyms_per_keycode) +#else +KeySym *XGetKeyboardMapping (dpy, first_keycode, count, keysyms_per_keycode) + register Display *dpy; + KeyCode first_keycode; + int count; + int *keysyms_per_keycode; /* RETURN */ +#endif +{ + long nbytes; + unsigned long nkeysyms; + register KeySym *mapping = NULL; + xGetKeyboardMappingReply rep; + register xGetKeyboardMappingReq *req; + + LockDisplay(dpy); + GetReq(GetKeyboardMapping, req); + req->firstKeyCode = first_keycode; + req->count = count; + if (! _XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return (KeySym *) NULL; + } + + nkeysyms = (unsigned long) rep.length; + if (nkeysyms > 0) { + nbytes = nkeysyms * sizeof (KeySym); + mapping = (KeySym *) Xmalloc ((unsigned) nbytes); + nbytes = nkeysyms << 2; + if (! mapping) { + _XEatData(dpy, (unsigned long) nbytes); + UnlockDisplay(dpy); + SyncHandle(); + return (KeySym *) NULL; + } + _XRead32 (dpy, (char *) mapping, nbytes); + } + *keysyms_per_keycode = rep.keySymsPerKeyCode; + UnlockDisplay(dpy); + SyncHandle(); + return (mapping); +} + diff --git a/src/GetProp.c b/src/GetProp.c new file mode 100644 index 00000000..ac8ef1c5 --- /dev/null +++ b/src/GetProp.c @@ -0,0 +1,129 @@ +/* $Xorg: GetProp.c,v 1.5 2001/02/09 02:03:33 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#define NEED_REPLIES +#include "Xlibint.h" + +int +XGetWindowProperty(dpy, w, property, offset, length, delete, + req_type, actual_type, actual_format, nitems, bytesafter, prop) + register Display *dpy; + Window w; + Atom property; + Bool delete; + Atom req_type; + Atom *actual_type; /* RETURN */ + int *actual_format; /* RETURN 8, 16, or 32 */ + long offset, length; + unsigned long *nitems; /* RETURN # of 8-, 16-, or 32-bit entities */ + unsigned long *bytesafter; /* RETURN */ + unsigned char **prop; /* RETURN */ +{ + xGetPropertyReply reply; + register xGetPropertyReq *req; + xError error; + + LockDisplay(dpy); + GetReq (GetProperty, req); + req->window = w; + req->property = property; + req->type = req_type; + req->delete = delete; + req->longOffset = offset; + req->longLength = length; + error.sequenceNumber = dpy->request; + + if (!_XReply (dpy, (xReply *) &reply, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return (1); /* not Success */ + } + + *prop = (unsigned char *) NULL; + if (reply.propertyType != None) { + long nbytes, netbytes; + switch (reply.format) { + /* + * One extra byte is malloced than is needed to contain the property + * data, but this last byte is null terminated and convenient for + * returning string properties, so the client doesn't then have to + * recopy the string to make it null terminated. + */ + case 8: + nbytes = netbytes = reply.nItems; + if ((*prop = (unsigned char *) Xmalloc ((unsigned)nbytes + 1))) + _XReadPad (dpy, (char *) *prop, netbytes); + break; + + case 16: + nbytes = reply.nItems * sizeof (short); + netbytes = reply.nItems << 1; + if ((*prop = (unsigned char *) Xmalloc ((unsigned)nbytes + 1))) + _XRead16Pad (dpy, (short *) *prop, netbytes); + break; + + case 32: + nbytes = reply.nItems * sizeof (long); + netbytes = reply.nItems << 2; + if ((*prop = (unsigned char *) Xmalloc ((unsigned)nbytes + 1))) + _XRead32 (dpy, (long *) *prop, netbytes); + break; + + default: + /* + * This part of the code should never be reached. If it is, + * the server sent back a property with an invalid format. + * This is a BadImplementation error. + */ + { + /* sequence number stored above */ + error.type = X_Error; + error.majorCode = X_GetProperty; + error.minorCode = 0; + error.errorCode = BadImplementation; + _XError(dpy, &error); + } + netbytes = 0L; + break; + } + if (! *prop) { + _XEatData(dpy, (unsigned long) netbytes); + UnlockDisplay(dpy); + SyncHandle(); + return(BadAlloc); /* not Success */ + } + (*prop)[nbytes] = '\0'; + } + *actual_type = reply.propertyType; + *actual_format = reply.format; + *nitems = reply.nItems; + *bytesafter = reply.bytesAfter; + UnlockDisplay(dpy); + SyncHandle(); + return(Success); +} + diff --git a/src/GetRGBCMap.c b/src/GetRGBCMap.c new file mode 100644 index 00000000..bde36215 --- /dev/null +++ b/src/GetRGBCMap.c @@ -0,0 +1,133 @@ +/* $Xorg: GetRGBCMap.c,v 1.4 2001/02/09 02:03:33 xorgcvs Exp $ */ + +/* + +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. + +*/ + +#include <X11/Xlibint.h> +#include <X11/Xutil.h> +#include "Xatomtype.h" +#include <X11/Xatom.h> + +Status XGetRGBColormaps (dpy, w, stdcmap, count, property) + Display *dpy; + Window w; + XStandardColormap **stdcmap; /* RETURN */ + int *count; /* RETURN */ + Atom property; /* XA_RGB_BEST_MAP, etc. */ +{ + register int i; /* iterator variable */ + xPropStandardColormap *data = NULL; /* data read in from prop */ + Atom actual_type; /* how the prop was actually stored */ + int actual_format; /* ditto */ + unsigned long leftover; /* how much was left over */ + unsigned long nitems; /* number of 32bits read */ + int ncmaps; /* number of structs this makes */ + Bool old_style = False; /* if was too short */ + VisualID def_visual = None; /* visual to use if prop too short */ + XStandardColormap *cmaps; /* return value */ + + + if (XGetWindowProperty (dpy, w, property, 0L, 1000000L, False, + XA_RGB_COLOR_MAP, &actual_type, &actual_format, + &nitems, &leftover, (unsigned char **)&data) + != Success) + return False; + + /* if wrong type or format, or too small for us, then punt */ + if ((actual_type != XA_RGB_COLOR_MAP) || (actual_format != 32) || + (nitems < OldNumPropStandardColormapElements)) { + if (data) Xfree ((char *) data); + return False; + } + + /* + * See how many properties were found; if pre-ICCCM then assume + * default visual and a kill id of 1. + */ + if (nitems < NumPropStandardColormapElements) { + ncmaps = 1; + old_style = True; + if (nitems < (NumPropStandardColormapElements - 1)) { + Screen *sp = _XScreenOfWindow (dpy, w); + + if (!sp) { + if (data) Xfree ((char *) data); + return False; + } + def_visual = sp->root_visual->visualid; + } + } else { + /* + * make sure we have an integral number of colormaps + */ + ncmaps = (nitems / NumPropStandardColormapElements); + if ((((unsigned long) ncmaps) * NumPropStandardColormapElements) != + nitems) { + if (data) Xfree ((char *) data); + return False; + } + } + + + /* + * allocate array + */ + cmaps = (XStandardColormap *) Xmalloc (ncmaps * + sizeof (XStandardColormap)); + if (!cmaps) { + if (data) Xfree ((char *) data); + return False; + } + + + /* + * and fill it in, handling compatibility with pre-ICCCM short stdcmaps + */ + { + register XStandardColormap *map; + register xPropStandardColormap *prop; + + for (i = ncmaps, map = cmaps, prop = data; i > 0; i--, map++, prop++) { + map->colormap = prop->colormap; + map->red_max = prop->red_max; + map->red_mult = prop->red_mult; + map->green_max = prop->green_max; + map->green_mult = prop->green_mult; + map->blue_max = prop->blue_max; + map->blue_mult = prop->blue_mult; + map->base_pixel = prop->base_pixel; + map->visualid = (def_visual ? def_visual : prop->visualid); + map->killid = (old_style ? None : prop->killid); + } + } + Xfree ((char *) data); + *stdcmap = cmaps; + *count = ncmaps; + return True; +} + diff --git a/src/GetSOwner.c b/src/GetSOwner.c new file mode 100644 index 00000000..b9bacdfc --- /dev/null +++ b/src/GetSOwner.c @@ -0,0 +1,44 @@ +/* $Xorg: GetSOwner.c,v 1.4 2001/02/09 02:03:33 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#define NEED_REPLIES +#include "Xlibint.h" + +Window XGetSelectionOwner(dpy, selection) +register Display *dpy; +Atom selection; +{ + xGetSelectionOwnerReply rep; + register xResourceReq *req; + LockDisplay(dpy); + GetResReq(GetSelectionOwner, selection, req); + + if (_XReply(dpy, (xReply *)&rep, 0, xTrue) == 0) rep.owner = None; + UnlockDisplay(dpy); + SyncHandle(); + return(rep.owner); +} diff --git a/src/GetSSaver.c b/src/GetSSaver.c new file mode 100644 index 00000000..60a7ef08 --- /dev/null +++ b/src/GetSSaver.c @@ -0,0 +1,52 @@ +/* $Xorg: GetSSaver.c,v 1.4 2001/02/09 02:03:33 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#define NEED_REPLIES +#include "Xlibint.h" + +XGetScreenSaver(dpy, timeout, interval, prefer_blanking, allow_exp) + register Display *dpy; + /* the following are return only vars */ + int *timeout, *interval; + int *prefer_blanking, *allow_exp; /*boolean */ + +{ + xGetScreenSaverReply rep; + register xReq *req; + LockDisplay(dpy); + GetEmptyReq(GetScreenSaver, req); + + (void) _XReply (dpy, (xReply *)&rep, 0, xTrue); + *timeout = rep.timeout; + *interval = rep.interval; + *prefer_blanking = rep.preferBlanking; + *allow_exp = rep.allowExposures; + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} + diff --git a/src/GetStCmap.c b/src/GetStCmap.c new file mode 100644 index 00000000..0674bcb8 --- /dev/null +++ b/src/GetStCmap.c @@ -0,0 +1,115 @@ +/* $Xorg: GetStCmap.c,v 1.4 2001/02/09 02:03:33 xorgcvs Exp $ */ + +/*********************************************************** + +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. + +******************************************************************/ + +#include <X11/Xlibint.h> +#include <X11/Xutil.h> +#include "Xatomtype.h" +#include <X11/Xatom.h> + +/* + * WARNING + * + * This is a pre-ICCCM routine. It must not reference any of the new fields + * in the XStandardColormap structure. + */ + +Status XGetStandardColormap (dpy, w, cmap, property) + Display *dpy; + Window w; + XStandardColormap *cmap; + Atom property; /* XA_RGB_BEST_MAP, etc. */ +{ + Status stat; /* return value */ + XStandardColormap *stdcmaps; /* will get malloced value */ + int nstdcmaps; /* count of above */ + + stat = XGetRGBColormaps (dpy, w, &stdcmaps, &nstdcmaps, property); + if (stat) { + XStandardColormap *use; + + if (nstdcmaps > 1) { + VisualID vid; + Screen *sp = _XScreenOfWindow (dpy, w); + int i; + + if (!sp) { + if (stdcmaps) Xfree ((char *) stdcmaps); + return False; + } + vid = sp->root_visual->visualid; + + for (i = 0; i < nstdcmaps; i++) { + if (stdcmaps[i].visualid == vid) break; + } + + if (i == nstdcmaps) { /* not found */ + Xfree ((char *) stdcmaps); + return False; + } + use = &stdcmaps[i]; + } else { + use = stdcmaps; + } + + /* + * assign only those fields which were in the pre-ICCCM version + */ + cmap->colormap = use->colormap; + cmap->red_max = use->red_max; + cmap->red_mult = use->red_mult; + cmap->green_max = use->green_max; + cmap->green_mult = use->green_mult; + cmap->blue_max = use->blue_max; + cmap->blue_mult = use->blue_mult; + cmap->base_pixel = use->base_pixel; + + Xfree ((char *) stdcmaps); /* don't need alloced memory */ + } + return stat; +} diff --git a/src/GetTxtProp.c b/src/GetTxtProp.c new file mode 100644 index 00000000..bbd62851 --- /dev/null +++ b/src/GetTxtProp.c @@ -0,0 +1,111 @@ +/* $Xorg: GetTxtProp.c,v 1.4 2001/02/09 02:03:33 xorgcvs Exp $ */ +/*********************************************************** +Copyright 1988 by Wyse Technology, Inc., San Jose, Ca., + + 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 Wyse not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +WYSE 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. + +******************************************************************/ +/* + +Copyright 1988, 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. + +*/ + +#include <X11/Xlibint.h> +#include <X11/Xatom.h> +#include <X11/Xutil.h> +#include <X11/Xos.h> +#include <stdio.h> + +Status XGetTextProperty (display, window, tp, property) + Display *display; + Window window; + XTextProperty *tp; + Atom property; +{ + Atom actual_type; + int actual_format = 0; + unsigned long nitems = 0L, leftover = 0L; + unsigned char *prop = NULL; + + if (XGetWindowProperty (display, window, property, 0L, 1000000L, False, + AnyPropertyType, &actual_type, &actual_format, + &nitems, &leftover, &prop) == Success && + actual_type != None) { + /* okay, fill it in */ + tp->value = prop; + tp->encoding = actual_type; + tp->format = actual_format; + tp->nitems = nitems; + return True; + } + + tp->value = NULL; + tp->encoding = None; + tp->format = 0; + tp->nitems = 0; + return False; +} + +Status XGetWMName (dpy, w, tp) + Display *dpy; + Window w; + XTextProperty *tp; +{ + return (XGetTextProperty (dpy, w, tp, XA_WM_NAME)); +} + +Status XGetWMIconName (dpy, w, tp) + Display *dpy; + Window w; + XTextProperty *tp; +{ + return (XGetTextProperty (dpy, w, tp, XA_WM_ICON_NAME)); +} + +Status XGetWMClientMachine (dpy, w, tp) + Display *dpy; + Window w; + XTextProperty *tp; +{ + return (XGetTextProperty (dpy, w, tp, XA_WM_CLIENT_MACHINE)); +} + diff --git a/src/GetWAttrs.c b/src/GetWAttrs.c new file mode 100644 index 00000000..7856b6f0 --- /dev/null +++ b/src/GetWAttrs.c @@ -0,0 +1,144 @@ +/* $Xorg: GetWAttrs.c,v 1.4 2001/02/09 02:03:33 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#define NEED_REPLIES +#include "Xlibint.h" + +typedef struct _WAttrsState { + unsigned long attr_seq; + unsigned long geom_seq; + XWindowAttributes *attr; +} _XWAttrsState; + +static Bool +_XWAttrsHandler(dpy, rep, buf, len, data) + register Display *dpy; + register xReply *rep; + char *buf; + int len; + XPointer data; +{ + register _XWAttrsState *state; + xGetWindowAttributesReply replbuf; + register xGetWindowAttributesReply *repl; + register XWindowAttributes *attr; + + state = (_XWAttrsState *)data; + if (dpy->last_request_read != state->attr_seq) { + if (dpy->last_request_read == state->geom_seq && + !state->attr && + rep->generic.type == X_Error && + rep->error.errorCode == BadDrawable) + return True; + return False; + } + if (rep->generic.type == X_Error) { + state->attr = (XWindowAttributes *)NULL; + return False; + } + repl = (xGetWindowAttributesReply *) + _XGetAsyncReply(dpy, (char *)&replbuf, rep, buf, len, + (SIZEOF(xGetWindowAttributesReply) - SIZEOF(xReply)) >> 2, + True); + attr = state->attr; + attr->class = repl->class; + attr->bit_gravity = repl->bitGravity; + attr->win_gravity = repl->winGravity; + attr->backing_store = repl->backingStore; + attr->backing_planes = repl->backingBitPlanes; + attr->backing_pixel = repl->backingPixel; + attr->save_under = repl->saveUnder; + attr->colormap = repl->colormap; + attr->map_installed = repl->mapInstalled; + attr->map_state = repl->mapState; + attr->all_event_masks = repl->allEventMasks; + attr->your_event_mask = repl->yourEventMask; + attr->do_not_propagate_mask = repl->doNotPropagateMask; + attr->override_redirect = repl->override; + attr->visual = _XVIDtoVisual (dpy, repl->visualID); + return True; +} + +Status XGetWindowAttributes(dpy, w, attr) + register Display *dpy; + Window w; + XWindowAttributes *attr; +{ + xGetGeometryReply rep; + register xResourceReq *req; + register int i; + register Screen *sp; + _XAsyncHandler async; + _XWAttrsState async_state; + + LockDisplay(dpy); + GetResReq(GetWindowAttributes, w, req); + + async_state.attr_seq = dpy->request; + async_state.geom_seq = 0; + async_state.attr = attr; + async.next = dpy->async_handlers; + async.handler = _XWAttrsHandler; + async.data = (XPointer)&async_state; + dpy->async_handlers = &async; + + GetResReq(GetGeometry, w, req); + + async_state.geom_seq = dpy->request; + + if (!_XReply (dpy, (xReply *)&rep, 0, xTrue)) { + DeqAsyncHandler(dpy, &async); + UnlockDisplay(dpy); + SyncHandle(); + return (0); + } + DeqAsyncHandler(dpy, &async); + if (!async_state.attr) { + UnlockDisplay(dpy); + SyncHandle(); + return (0); + } + attr->x = cvtINT16toInt (rep.x); + attr->y = cvtINT16toInt (rep.y); + attr->width = rep.width; + attr->height = rep.height; + attr->border_width = rep.borderWidth; + attr->depth = rep.depth; + attr->root = rep.root; + /* find correct screen so that applications find it easier.... */ + for (i = 0; i < dpy->nscreens; i++) { + sp = &dpy->screens[i]; + if (sp->root == attr->root) { + attr->screen = sp; + break; + } + } + UnlockDisplay(dpy); + SyncHandle(); + return(1); +} + diff --git a/src/GetWMCMapW.c b/src/GetWMCMapW.c new file mode 100644 index 00000000..6c56a136 --- /dev/null +++ b/src/GetWMCMapW.c @@ -0,0 +1,85 @@ +/* $Xorg: GetWMCMapW.c,v 1.4 2001/02/09 02:03:33 xorgcvs Exp $ */ + +/*********************************************************** + +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. + +******************************************************************/ + +#include "Xlibint.h" +#include <X11/Xatom.h> +#include <stdio.h> + +Status XGetWMColormapWindows (dpy, w, colormapWindows, countReturn) + Display *dpy; + Window w; + Window **colormapWindows; + int *countReturn; +{ + Atom *data = NULL; + Atom actual_type; + Atom prop; + int actual_format; + unsigned long leftover, nitems; + + prop = XInternAtom(dpy, "WM_COLORMAP_WINDOWS", False); + if (prop == None) return False; + + /* get the property */ + if (XGetWindowProperty (dpy, w, prop, + 0L, 1000000L, False, + XA_WINDOW, &actual_type, &actual_format, + &nitems, &leftover, (unsigned char **) &data) + != Success) + return False; + + if (actual_type != XA_WINDOW || actual_format != 32) { + if (data) Xfree ((char *) data); + return False; + } + + *colormapWindows = (Window *) data; + *countReturn = (int) nitems; + return True; +} diff --git a/src/GetWMProto.c b/src/GetWMProto.c new file mode 100644 index 00000000..84e79b60 --- /dev/null +++ b/src/GetWMProto.c @@ -0,0 +1,85 @@ +/* $Xorg: GetWMProto.c,v 1.4 2001/02/09 02:03:33 xorgcvs Exp $ */ + +/*********************************************************** + +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. + +******************************************************************/ + +#include "Xlibint.h" +#include <X11/Xatom.h> +#include <stdio.h> + +Status XGetWMProtocols (dpy, w, protocols, countReturn) + Display *dpy; + Window w; + Atom **protocols; + int *countReturn; +{ + Atom *data = NULL; + Atom actual_type; + Atom prop; + int actual_format; + unsigned long leftover, nitems; + + prop = XInternAtom(dpy, "WM_PROTOCOLS", False); + if (prop == None) return False; + + /* get the property */ + if (XGetWindowProperty (dpy, w, prop, + 0L, 1000000L, False, + XA_ATOM, &actual_type, &actual_format, + &nitems, &leftover, (unsigned char **) &data) + != Success) + return False; + + if (actual_type != XA_ATOM || actual_format != 32) { + if (data) Xfree ((char *) data); + return False; + } + + *protocols = (Atom *) data; + *countReturn = (int) nitems; + return True; +} diff --git a/src/GrButton.c b/src/GrButton.c new file mode 100644 index 00000000..f0a8ebfb --- /dev/null +++ b/src/GrButton.c @@ -0,0 +1,57 @@ +/* $Xorg: GrButton.c,v 1.4 2001/02/09 02:03:33 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XGrabButton(dpy, button, modifiers, grab_window, owner_events, event_mask, + pointer_mode, keyboard_mode, confine_to, curs) +register Display *dpy; +unsigned int modifiers; /* CARD16 */ +unsigned int button; /* CARD8 */ +Window grab_window; +Bool owner_events; +unsigned int event_mask; /* CARD16 */ +int pointer_mode, keyboard_mode; +Window confine_to; +Cursor curs; +{ + register xGrabButtonReq *req; + LockDisplay(dpy); + GetReq(GrabButton, req); + req->modifiers = modifiers; + req->button = button; + req->grabWindow = grab_window; + req->ownerEvents = owner_events; + req->eventMask = event_mask; + req->pointerMode = pointer_mode; + req->keyboardMode = keyboard_mode; + req->confineTo = confine_to; + req->cursor = curs; + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} diff --git a/src/GrKey.c b/src/GrKey.c new file mode 100644 index 00000000..4f339b75 --- /dev/null +++ b/src/GrKey.c @@ -0,0 +1,55 @@ +/* $Xorg: GrKey.c,v 1.4 2001/02/09 02:03:33 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XGrabKey(dpy, key, modifiers, grab_window, owner_events, + pointer_mode, keyboard_mode) + register Display *dpy; + int key; + unsigned int modifiers; + Window grab_window; + Bool owner_events; + int pointer_mode, keyboard_mode; + +{ + register xGrabKeyReq *req; + LockDisplay(dpy); + GetReq(GrabKey, req); + req->ownerEvents = owner_events; + req->grabWindow = grab_window; + req->modifiers = modifiers; + req->key = key; + req->pointerMode = pointer_mode; + req->keyboardMode = keyboard_mode; + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} + + + diff --git a/src/GrKeybd.c b/src/GrKeybd.c new file mode 100644 index 00000000..3f43f7ae --- /dev/null +++ b/src/GrKeybd.c @@ -0,0 +1,56 @@ +/* $Xorg: GrKeybd.c,v 1.4 2001/02/09 02:03:33 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#define NEED_REPLIES +#include "Xlibint.h" +int XGrabKeyboard (dpy, window, ownerEvents, pointerMode, keyboardMode, time) + register Display *dpy; + Window window; + Bool ownerEvents; + int pointerMode, keyboardMode; + Time time; +{ + xGrabKeyboardReply rep; + register xGrabKeyboardReq *req; + register int status; + LockDisplay(dpy); + GetReq(GrabKeyboard, req); + req->grabWindow = window; + req->ownerEvents = ownerEvents; + req->pointerMode = pointerMode; + req->keyboardMode = keyboardMode; + req->time = time; + + /* if we ever return, suppress the error */ + if (_XReply (dpy, (xReply *) &rep, 0, xTrue) == 0) + rep.status = GrabSuccess; + status = rep.status; + UnlockDisplay(dpy); + SyncHandle(); + return (status); +} + diff --git a/src/GrPointer.c b/src/GrPointer.c new file mode 100644 index 00000000..544337a9 --- /dev/null +++ b/src/GrPointer.c @@ -0,0 +1,63 @@ +/* $Xorg: GrPointer.c,v 1.4 2001/02/09 02:03:33 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#define NEED_REPLIES +#include "Xlibint.h" + +int XGrabPointer(dpy, grab_window, owner_events, event_mask, pointer_mode, + keyboard_mode, confine_to, curs, time) +register Display *dpy; +Window grab_window; +Bool owner_events; +unsigned int event_mask; /* CARD16 */ +int pointer_mode, keyboard_mode; +Window confine_to; +Cursor curs; +Time time; +{ + xGrabPointerReply rep; + register xGrabPointerReq *req; + register int status; + LockDisplay(dpy); + GetReq(GrabPointer, req); + req->grabWindow = grab_window; + req->ownerEvents = owner_events; + req->eventMask = event_mask; + req->pointerMode = pointer_mode; + req->keyboardMode = keyboard_mode; + req->confineTo = confine_to; + req->cursor = curs; + req->time = time; + + /* if we ever return, suppress the error */ + if (_XReply (dpy, (xReply *) &rep, 0, xTrue) == 0) + rep.status = GrabSuccess; + status = rep.status; + UnlockDisplay(dpy); + SyncHandle(); + return (status); +} diff --git a/src/GrServer.c b/src/GrServer.c new file mode 100644 index 00000000..9dfc04ac --- /dev/null +++ b/src/GrServer.c @@ -0,0 +1,40 @@ +/* $Xorg: GrServer.c,v 1.4 2001/02/09 02:03:33 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XGrabServer (dpy) +register Display *dpy; +{ + register xReq *req; + LockDisplay(dpy); + GetEmptyReq(GrabServer, req); + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} + diff --git a/src/Host.c b/src/Host.c new file mode 100644 index 00000000..863ff8ef --- /dev/null +++ b/src/Host.c @@ -0,0 +1,91 @@ +/* $Xorg: Host.c,v 1.4 2001/02/09 02:03:33 xorgcvs Exp $ */ +/* + +Copyright 1986, 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 might be rightly reguarded an os dependent file */ + +#include "Xlibint.h" + +XAddHost (dpy, host) + register Display *dpy; + XHostAddress *host; + { + register xChangeHostsReq *req; + register int length = (host->length + 3) & ~0x3; /* round up */ + + LockDisplay(dpy); + GetReqExtra (ChangeHosts, length, req); + req->mode = HostInsert; + req->hostFamily = host->family; + req->hostLength = host->length; + memcpy((char *) NEXTPTR(req,xChangeHostsReq), host->address, host->length); + UnlockDisplay(dpy); + SyncHandle(); + return 1; + } + +XRemoveHost (dpy, host) + register Display *dpy; + XHostAddress *host; + { + register xChangeHostsReq *req; + register int length = (host->length + 3) & ~0x3; /* round up */ + + LockDisplay(dpy); + GetReqExtra (ChangeHosts, length, req); + req->mode = HostDelete; + req->hostFamily = host->family; + req->hostLength = host->length; + memcpy((char *) NEXTPTR(req,xChangeHostsReq), host->address, host->length); + UnlockDisplay(dpy); + SyncHandle(); + return 1; + } + + +XAddHosts (dpy, hosts, n) + register Display *dpy; + XHostAddress *hosts; + int n; +{ + register int i; + for (i = 0; i < n; i++) { + (void) XAddHost(dpy, &hosts[i]); + } + return 1; +} + +XRemoveHosts (dpy, hosts, n) + register Display *dpy; + XHostAddress *hosts; + int n; +{ + register int i; + for (i = 0; i < n; i++) { + (void) XRemoveHost(dpy, &hosts[i]); + } + return 1; +} diff --git a/src/Iconify.c b/src/Iconify.c new file mode 100644 index 00000000..b67b6602 --- /dev/null +++ b/src/Iconify.c @@ -0,0 +1,84 @@ +/* $Xorg: Iconify.c,v 1.4 2001/02/09 02:03:33 xorgcvs Exp $ */ + +/*********************************************************** +Copyright 1988 by Wyse Technology, Inc., San Jose, Ca. + + 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 Wyse not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +WYSE 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. + +******************************************************************/ +/* + +Copyright 1988, 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. + +*/ + +#define NEED_EVENTS +#include <X11/Xlibint.h> +#include <X11/Xatom.h> +#include <X11/Xos.h> +#include <X11/Xutil.h> +#include <stdio.h> + +/* + * This function instructs the window manager to change this window from + * NormalState to IconicState. + */ +Status XIconifyWindow (dpy, w, screen) + Display *dpy; + Window w; + int screen; +{ + XClientMessageEvent ev; + Window root = RootWindow (dpy, screen); + Atom prop; + + prop = XInternAtom (dpy, "WM_CHANGE_STATE", False); + if (prop == None) return False; + + ev.type = ClientMessage; + ev.window = w; + ev.message_type = prop; + ev.format = 32; + ev.data.l[0] = IconicState; + return (XSendEvent (dpy, root, False, + SubstructureRedirectMask|SubstructureNotifyMask, + (XEvent *)&ev)); +} diff --git a/src/IfEvent.c b/src/IfEvent.c new file mode 100644 index 00000000..975d77a1 --- /dev/null +++ b/src/IfEvent.c @@ -0,0 +1,72 @@ +/* $Xorg: IfEvent.c,v 1.4 2001/02/09 02:03:34 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#define NEED_EVENTS +#include "Xlibint.h" + +/* + * Flush output and (wait for and) return the next event matching the + * predicate in the queue. + */ + +XIfEvent (dpy, event, predicate, arg) + register Display *dpy; + Bool (*predicate)( +#if NeedNestedPrototypes + Display* /* display */, + XEvent* /* event */, + char* /* arg */ +#endif + ); /* function to call */ + register XEvent *event; + char *arg; +{ + register _XQEvent *qelt, *prev; + unsigned long qe_serial = 0; + + LockDisplay(dpy); + prev = NULL; + while (1) { + for (qelt = prev ? prev->next : dpy->head; + qelt; + prev = qelt, qelt = qelt->next) { + if(qelt->qserial_num > qe_serial + && (*predicate)(dpy, &qelt->event, arg)) { + *event = qelt->event; + _XDeq(dpy, prev, qelt); + UnlockDisplay(dpy); + return 0; + } + } + if (prev) + qe_serial = prev->qserial_num; + _XReadEvents(dpy); + if (prev && prev->qserial_num != qe_serial) + /* another thread has snatched this event */ + prev = NULL; + } +} diff --git a/src/ImText.c b/src/ImText.c new file mode 100644 index 00000000..45f17983 --- /dev/null +++ b/src/ImText.c @@ -0,0 +1,109 @@ +/* $Xorg: ImText.c,v 1.4 2001/02/09 02:03:34 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#define NEED_REPLIES +#include "Xlibint.h" + +#if NeedFunctionPrototypes +XDrawImageString( + register Display *dpy, + Drawable d, + GC gc, + int x, + int y, + _Xconst char *string, + int length) +#else +XDrawImageString(dpy, d, gc, x, y, string, length) + register Display *dpy; + Drawable d; + GC gc; + int x, y; + char *string; + int length; +#endif +{ + register xImageText8Req *req; + char *CharacterOffset = (char *)string; + int FirstTimeThrough = True; + int lastX = 0; + + LockDisplay(dpy); + FlushGC(dpy, gc); + + while (length > 0) + { + int Unit; + + if (length > 255) Unit = 255; + else Unit = length; + + if (FirstTimeThrough) + { + FirstTimeThrough = False; + } + else + { + char buf[512]; + char *ptr, *str; + xQueryTextExtentsReq *qreq; + xQueryTextExtentsReply rep; + int i; + + GetReq(QueryTextExtents, qreq); + qreq->fid = gc->gid; + qreq->length += (510 + 3)>>2; + qreq->oddLength = 1; + str = CharacterOffset - 255; + for (ptr = buf, i = 255; --i >= 0; ) { + *ptr++ = 0; + *ptr++ = *str++; + } + Data (dpy, buf, 510); + if (!_XReply (dpy, (xReply *)&rep, 0, xTrue)) + break; + + x = lastX + cvtINT32toInt (rep.overallWidth); + } + + GetReq (ImageText8, req); + req->length += (Unit + 3) >> 2; + req->nChars = Unit; + req->drawable = d; + req->gc = gc->gid; + req->y = y; + + lastX = req->x = x; + Data (dpy, CharacterOffset, (long)Unit); + CharacterOffset += Unit; + length -= Unit; + } + UnlockDisplay(dpy); + SyncHandle(); + return 0; +} + diff --git a/src/ImText16.c b/src/ImText16.c new file mode 100644 index 00000000..fdc171ad --- /dev/null +++ b/src/ImText16.c @@ -0,0 +1,111 @@ +/* $Xorg: ImText16.c,v 1.4 2001/02/09 02:03:34 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#define NEED_REPLIES +#include "Xlibint.h" + +#if NeedFunctionPrototypes +XDrawImageString16( + register Display *dpy, + Drawable d, + GC gc, + int x, + int y, + _Xconst XChar2b *string, + int length) +#else +XDrawImageString16(dpy, d, gc, x, y, string, length) + register Display *dpy; + Drawable d; + GC gc; + int x, y; + XChar2b *string; + int length; +#endif +{ + register xImageText16Req *req; + XChar2b *CharacterOffset = (XChar2b *)string; + int FirstTimeThrough = True; + int lastX = 0; + + LockDisplay(dpy); + FlushGC(dpy, gc); + + while (length > 0) + { + int Unit, Datalength; + + if (length > 255) Unit = 255; + else Unit = length; + + if (FirstTimeThrough) + { + FirstTimeThrough = False; + } + else + { + char buf[512]; + xQueryTextExtentsReq *qreq; + xQueryTextExtentsReply rep; + unsigned char *ptr; + XChar2b *str; + int i; + + GetReq(QueryTextExtents, qreq); + qreq->fid = gc->gid; + qreq->length += (510 + 3)>>2; + qreq->oddLength = 1; + str = CharacterOffset - 255; + for (ptr = (unsigned char *)buf, i = 255; --i >= 0; str++) { + *ptr++ = str->byte1; + *ptr++ = str->byte2; + } + Data (dpy, buf, 510); + if (!_XReply (dpy, (xReply *)&rep, 0, xTrue)) + break; + + x = lastX + cvtINT32toInt (rep.overallWidth); + } + + GetReq (ImageText16, req); + req->length += ((Unit << 1) + 3) >> 2; + req->nChars = Unit; + req->drawable = d; + req->gc = gc->gid; + req->y = y; + + lastX = req->x = x; + Datalength = Unit << 1; + Data (dpy, (char *)CharacterOffset, (long)Datalength); + CharacterOffset += Unit; + length -= Unit; + } + UnlockDisplay(dpy); + SyncHandle(); + return 0; +} + diff --git a/src/ImUtil.c b/src/ImUtil.c new file mode 100644 index 00000000..b358e511 --- /dev/null +++ b/src/ImUtil.c @@ -0,0 +1,1016 @@ +/* $Xorg: ImUtil.c,v 1.4 2001/02/09 02:03:34 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include <X11/Xlibint.h> +#include <X11/Xutil.h> +#include <stdio.h> + +#ifdef __STDC__ +#define Const const +#else +#define Const /**/ +#endif + +#if NeedFunctionPrototypes +static int _XDestroyImage(XImage *); +static unsigned long _XGetPixel(XImage *, int, int); +static unsigned long _XGetPixel1(XImage *, int, int); +static unsigned long _XGetPixel8(XImage *, int, int); +static unsigned long _XGetPixel16(XImage *, int, int); +static unsigned long _XGetPixel32(XImage *, int, int); +static int _XPutPixel(XImage *, int, int, unsigned long); +static int _XPutPixel1(XImage *, int, int, unsigned long); +static int _XPutPixel8(XImage *, int, int, unsigned long); +static int _XPutPixel16(XImage *, int, int, unsigned long); +static int _XPutPixel32(XImage *, int, int, unsigned long); +static XImage *_XSubImage(XImage *, int, int, unsigned int, unsigned int); +static int _XAddPixel(XImage *, long); +#endif + +static unsigned char Const _lomask[0x09] = { 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff }; +static unsigned char Const _himask[0x09] = { 0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00 }; + +/* These two convenience routines return the scanline_pad and bits_per_pixel + associated with a specific depth of ZPixmap format image for a + display. */ + + _XGetScanlinePad(dpy, depth) + Display *dpy; + int depth; + { + register ScreenFormat *fmt = dpy->pixmap_format; + register int i; + + for (i = dpy->nformats + 1; --i; ++fmt) + if (fmt->depth == depth) + return(fmt->scanline_pad); + + return(dpy->bitmap_pad); + } + + _XGetBitsPerPixel(dpy, depth) + Display *dpy; + int depth; + { + register ScreenFormat *fmt = dpy->pixmap_format; + register int i; + + for (i = dpy->nformats + 1; --i; ++fmt) + if (fmt->depth == depth) + return(fmt->bits_per_pixel); + if (depth <= 4) + return 4; + if (depth <= 8) + return 8; + if (depth <= 16) + return 16; + return 32; + } + + +/* + * This module provides rudimentary manipulation routines for image data + * structures. The functions provided are: + * + * XCreateImage Creates a default XImage data structure + * _XDestroyImage Deletes an XImage data structure + * _XGetPixel Reads a pixel from an image data structure + * _XGetPixel32 Reads a pixel from a 32-bit Z image data structure + * _XGetPixel16 Reads a pixel from a 16-bit Z image data structure + * _XGetPixel8 Reads a pixel from an 8-bit Z image data structure + * _XGetPixel1 Reads a pixel from an 1-bit image data structure + * _XPutPixel Writes a pixel into an image data structure + * _XPutPixel32 Writes a pixel into a 32-bit Z image data structure + * _XPutPixel16 Writes a pixel into a 16-bit Z image data structure + * _XPutPixel8 Writes a pixel into an 8-bit Z image data structure + * _XPutPixel1 Writes a pixel into an 1-bit image data structure + * _XSubImage Clones a new (sub)image from an existing one + * _XSetImage Writes an image data pattern into another image + * _XAddPixel Adds a constant value to every pixel in an image + * + * The logic contained in these routines makes several assumptions about + * the image data structures, and at least for current implementations + * these assumptions are believed to be true. They are: + * + * For all formats, bits_per_pixel is less than or equal to 32. + * For XY formats, bitmap_unit is always less than or equal to bitmap_pad. + * For XY formats, bitmap_unit is 8, 16, or 32 bits. + * For Z format, bits_per_pixel is 1, 4, 8, 16, 24, or 32 bits. + */ +static void _xynormalizeimagebits (bp, img) + register unsigned char *bp; + register XImage *img; +{ + register unsigned char c; + + if (img->byte_order != img->bitmap_bit_order) { + switch (img->bitmap_unit) { + + case 16: + c = *bp; + *bp = *(bp + 1); + *(bp + 1) = c; + break; + + case 32: + c = *(bp + 3); + *(bp + 3) = *bp; + *bp = c; + c = *(bp + 2); + *(bp + 2) = *(bp + 1); + *(bp + 1) = c; + break; + } + } + if (img->bitmap_bit_order == MSBFirst) + _XReverse_Bytes (bp, img->bitmap_unit >> 3); +} + +static void _znormalizeimagebits (bp, img) + register unsigned char *bp; + register XImage *img; +{ + register unsigned char c; + switch (img->bits_per_pixel) { + + case 4: + *bp = ((*bp >> 4) & 0xF) | ((*bp << 4) & ~0xF); + break; + + case 16: + c = *bp; + *bp = *(bp + 1); + *(bp + 1) = c; + break; + + case 24: + c = *(bp + 2); + *(bp + 2) = *bp; + *bp = c; + break; + + case 32: + c = *(bp + 3); + *(bp + 3) = *bp; + *bp = c; + c = *(bp + 2); + *(bp + 2) = *(bp + 1); + *(bp + 1) = c; + break; + } +} + +static void _putbits (src, dstoffset, numbits, dst) + register char *src; /* address of source bit string */ + int dstoffset; /* bit offset into destination; range is 0-31 */ + register int numbits;/* number of bits to copy to destination */ + register char *dst; /* address of destination bit string */ +{ + register unsigned char chlo, chhi; + int hibits; + dst = dst + (dstoffset >> 3); + dstoffset = dstoffset & 7; + hibits = 8 - dstoffset; + chlo = *dst & _lomask[dstoffset]; + for (;;) { + chhi = (*src << dstoffset) & _himask[dstoffset]; + if (numbits <= hibits) { + chhi = chhi & _lomask[dstoffset + numbits]; + *dst = (*dst & _himask[dstoffset + numbits]) | chlo | chhi; + break; + } + *dst = chhi | chlo; + dst++; + numbits = numbits - hibits; + chlo = (unsigned char) (*src & _himask[hibits]) >> hibits; + src++; + if (numbits <= dstoffset) { + chlo = chlo & _lomask[numbits]; + *dst = (*dst & _himask[numbits]) | chlo; + break; + } + numbits = numbits - dstoffset; + } +} + + +/* + * Macros + * + * The ROUNDUP macro rounds up a quantity to the specified boundary, + * then truncates to bytes. + * + * The XYNORMALIZE macro determines whether XY format data requires + * normalization and calls a routine to do so if needed. The logic in + * this module is designed for LSBFirst byte and bit order, so + * normalization is done as required to present the data in this order. + * + * The ZNORMALIZE macro performs byte and nibble order normalization if + * required for Z format data. + * + * The XYINDEX macro computes the index to the starting byte (char) boundary + * for a bitmap_unit containing a pixel with coordinates x and y for image + * data in XY format. + * + * The ZINDEX macro computes the index to the starting byte (char) boundary + * for a pixel with coordinates x and y for image data in ZPixmap format. + * + */ + +#define ROUNDUP(nbytes, pad) ((((nbytes) + ((pad)-1)) / (pad)) * ((pad)>>3)) + +#define XYNORMALIZE(bp, img) \ + if ((img->byte_order == MSBFirst) || (img->bitmap_bit_order == MSBFirst)) \ + _xynormalizeimagebits((unsigned char *)(bp), img) + +#define ZNORMALIZE(bp, img) \ + if (img->byte_order == MSBFirst) \ + _znormalizeimagebits((unsigned char *)(bp), img) + +#define XYINDEX(x, y, img) \ + ((y) * img->bytes_per_line) + \ + (((x) + img->xoffset) / img->bitmap_unit) * (img->bitmap_unit >> 3) + +#define ZINDEX(x, y, img) ((y) * img->bytes_per_line) + \ + (((x) * img->bits_per_pixel) >> 3) + +/* + * This routine initializes the image object function pointers. The + * intent is to provide native (i.e. fast) routines for native format images + * only using the generic (i.e. slow) routines when fast ones don't exist. + * However, with the current rather botched external interface, clients may + * have to mung image attributes after the image gets created, so the fast + * routines always have to check to make sure the optimization is still + * valid, and reinit the functions if not. + */ +void _XInitImageFuncPtrs (image) + register XImage *image; +{ + image->f.create_image = XCreateImage; + image->f.destroy_image = _XDestroyImage; + if ((image->format == ZPixmap) && (image->bits_per_pixel == 8)) { + image->f.get_pixel = _XGetPixel8; + image->f.put_pixel = _XPutPixel8; + } else if (((image->bits_per_pixel | image->depth) == 1) && + (image->byte_order == image->bitmap_bit_order)) { + image->f.get_pixel = _XGetPixel1; + image->f.put_pixel = _XPutPixel1; + } else if ((image->format == ZPixmap) && + (image->bits_per_pixel == 32)) { + image->f.get_pixel = _XGetPixel32; + image->f.put_pixel = _XPutPixel32; + } else if ((image->format == ZPixmap) && + (image->bits_per_pixel == 16)) { + image->f.get_pixel = _XGetPixel16; + image->f.put_pixel = _XPutPixel16; + } else { + image->f.get_pixel = _XGetPixel; + image->f.put_pixel = _XPutPixel; + } + image->f.sub_image = _XSubImage; +/* image->f.set_image = _XSetImage;*/ + image->f.add_pixel = _XAddPixel; +} + +/* + * CreateImage + * + * Allocates the memory necessary for an XImage data structure. + * Initializes the structure with "default" values and returns XImage. + * + */ + +XImage *XCreateImage (dpy, visual, depth, format, offset, data, width, height, + xpad, image_bytes_per_line) + register Display *dpy; + register Visual *visual; + unsigned int depth; + int format; + int offset; /*How many pixels from the start of the data does the + picture to be transmitted start?*/ + + char *data; + unsigned int width; + unsigned int height; + int xpad; + int image_bytes_per_line; + /*How many bytes between a pixel on one line and the pixel with + the same X coordinate on the next line? 0 means + XCreateImage can calculate it.*/ +{ + register XImage *image; + int bits_per_pixel = 1; + + if (depth == 0 || depth > 32 || + (format != XYBitmap && format != XYPixmap && format != ZPixmap) || + (format == XYBitmap && depth != 1) || + (xpad != 8 && xpad != 16 && xpad != 32) || + offset < 0 || image_bytes_per_line < 0) + return (XImage *) NULL; + if ((image = (XImage *) Xcalloc(1, (unsigned) sizeof(XImage))) == NULL) + return (XImage *) NULL; + + image->width = width; + image->height = height; + image->format = format; + image->byte_order = dpy->byte_order; + image->bitmap_unit = dpy->bitmap_unit; + image->bitmap_bit_order = dpy->bitmap_bit_order; + if (visual != NULL) { + image->red_mask = visual->red_mask; + image->green_mask = visual->green_mask; + image->blue_mask = visual->blue_mask; + } + else { + image->red_mask = image->green_mask = image->blue_mask = 0; + } + if (format == ZPixmap) + { + bits_per_pixel = _XGetBitsPerPixel(dpy, (int) depth); + } + + image->xoffset = offset; + image->bitmap_pad = xpad; + image->depth = depth; + image->data = data; + /* + * compute per line accelerator. + */ + if (image_bytes_per_line == 0) + { + if (format == ZPixmap) + image->bytes_per_line = + ROUNDUP((bits_per_pixel * width), image->bitmap_pad); + else + image->bytes_per_line = + ROUNDUP((width + offset), image->bitmap_pad); + } + else image->bytes_per_line = image_bytes_per_line; + + image->bits_per_pixel = bits_per_pixel; + image->obdata = NULL; + _XInitImageFuncPtrs (image); + + return image; +} + +Status XInitImage (image) + XImage *image; +{ + if (image->depth == 0 || image->depth > 32 || + (image->format != XYBitmap && + image->format != XYPixmap && + image->format != ZPixmap) || + (image->format == XYBitmap && image->depth != 1) || + (image->bitmap_pad != 8 && + image->bitmap_pad != 16 && + image->bitmap_pad != 32) || + image->xoffset < 0 || image->bytes_per_line < 0) + return 0; + + /* + * compute per line accelerator. + */ + if (image->bytes_per_line == 0) + { + if (image->format == ZPixmap) + image->bytes_per_line = + ROUNDUP((image->bits_per_pixel * image->width), + image->bitmap_pad); + else + image->bytes_per_line = + ROUNDUP((image->width + image->xoffset), image->bitmap_pad); + } + + _XInitImageFuncPtrs (image); + + return 1; +} + +/* + * _DestroyImage + * + * Deallocates the memory associated with the ximage data structure. + * this version handles the case of the image data being malloc'd + * entirely by the library. + */ + +static int _XDestroyImage (ximage) + XImage *ximage; + +{ + if (ximage->data != NULL) Xfree((char *)ximage->data); + if (ximage->obdata != NULL) Xfree((char *)ximage->obdata); + Xfree((char *)ximage); + return 1; +} + + +/* + * GetPixel + * + * Returns the specified pixel. The X and Y coordinates are relative to + * the origin (upper left [0,0]) of the image. The pixel value is returned + * in normalized format, i.e. the LSB of the long is the LSB of the pixel. + * The algorithm used is: + * + * copy the source bitmap_unit or Zpixel into temp + * normalize temp if needed + * extract the pixel bits into return value + * + */ + +static unsigned long Const low_bits_table[] = { + 0x00000000, 0x00000001, 0x00000003, 0x00000007, + 0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f, + 0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff, + 0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff, + 0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff, + 0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff, + 0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff, + 0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff, + 0xffffffff +}; + +static unsigned long _XGetPixel (ximage, x, y) + register XImage *ximage; + int x; + int y; + +{ + unsigned long pixel, px; + register char *src; + register char *dst; + register int i, j; + int bits, nbytes; + long plane; + + if ((ximage->bits_per_pixel | ximage->depth) == 1) { + src = &ximage->data[XYINDEX(x, y, ximage)]; + dst = (char *)&pixel; + pixel = 0; + for (i = ximage->bitmap_unit >> 3; --i >= 0; ) *dst++ = *src++; + XYNORMALIZE(&pixel, ximage); + bits = (x + ximage->xoffset) % ximage->bitmap_unit; + pixel = ((((char *)&pixel)[bits>>3])>>(bits&7)) & 1; + } else if (ximage->format == XYPixmap) { + pixel = 0; + plane = 0; + nbytes = ximage->bitmap_unit >> 3; + for (i = ximage->depth; --i >= 0; ) { + src = &ximage->data[XYINDEX(x, y, ximage)+ plane]; + dst = (char *)&px; + px = 0; + for (j = nbytes; --j >= 0; ) *dst++ = *src++; + XYNORMALIZE(&px, ximage); + bits = (x + ximage->xoffset) % ximage->bitmap_unit; + pixel = (pixel << 1) | + (((((char *)&px)[bits>>3])>>(bits&7)) & 1); + plane = plane + (ximage->bytes_per_line * ximage->height); + } + } else if (ximage->format == ZPixmap) { + src = &ximage->data[ZINDEX(x, y, ximage)]; + dst = (char *)&px; + px = 0; + for (i = (ximage->bits_per_pixel + 7) >> 3; --i >= 0; ) + *dst++ = *src++; + ZNORMALIZE(&px, ximage); + pixel = 0; + for (i=sizeof(unsigned long); --i >= 0; ) + pixel = (pixel << 8) | ((unsigned char *)&px)[i]; + if (ximage->bits_per_pixel == 4) { + if (x & 1) + pixel >>= 4; + else + pixel &= 0xf; + } + } else { + return 0; /* bad image */ + } + if (ximage->bits_per_pixel == ximage->depth) + return pixel; + else + return (pixel & low_bits_table[ximage->depth]); +} + +#ifndef WORD64 +static unsigned long byteorderpixel = MSBFirst << 24; +#endif + +static unsigned long _XGetPixel32 (ximage, x, y) + register XImage *ximage; + int x; + int y; +{ + register unsigned char *addr; + unsigned long pixel; + + if ((ximage->format == ZPixmap) && (ximage->bits_per_pixel == 32)) { + addr = &((unsigned char *)ximage->data) + [y * ximage->bytes_per_line + (x << 2)]; +#ifndef WORD64 + if (*((char *)&byteorderpixel) == ximage->byte_order) + pixel = *((CARD32 *)addr); + else +#endif + if (ximage->byte_order == MSBFirst) + pixel = ((unsigned long)addr[0] << 24 | + (unsigned long)addr[1] << 16 | + (unsigned long)addr[2] << 8 | + addr[3]); + else + pixel = ((unsigned long)addr[3] << 24 | + (unsigned long)addr[2] << 16 | + (unsigned long)addr[1] << 8 | + addr[0]); + if (ximage->depth != 32) + pixel &= low_bits_table[ximage->depth]; + return pixel; + } else { + _XInitImageFuncPtrs(ximage); + return XGetPixel(ximage, x, y); + } +} + +static unsigned long _XGetPixel16 (ximage, x, y) + register XImage *ximage; + int x; + int y; +{ + register unsigned char *addr; + unsigned long pixel; + + if ((ximage->format == ZPixmap) && (ximage->bits_per_pixel == 16)) { + addr = &((unsigned char *)ximage->data) + [y * ximage->bytes_per_line + (x << 1)]; + if (ximage->byte_order == MSBFirst) + pixel = addr[0] << 8 | addr[1]; + else + pixel = addr[1] << 8 | addr[0]; + if (ximage->depth != 16) + pixel &= low_bits_table[ximage->depth]; + return pixel; + } else { + _XInitImageFuncPtrs(ximage); + return XGetPixel(ximage, x, y); + } +} + +static unsigned long _XGetPixel8 (ximage, x, y) + register XImage *ximage; + int x; + int y; +{ + unsigned char pixel; + + if ((ximage->format == ZPixmap) && (ximage->bits_per_pixel == 8)) { + pixel = ((unsigned char *)ximage->data) + [y * ximage->bytes_per_line + x]; + if (ximage->depth != 8) + pixel &= low_bits_table[ximage->depth]; + return pixel; + } else { + _XInitImageFuncPtrs(ximage); + return XGetPixel(ximage, x, y); + } +} + +static unsigned long _XGetPixel1 (ximage, x, y) + register XImage *ximage; + int x; + int y; +{ + unsigned char bit; + int xoff, yoff; + + if (((ximage->bits_per_pixel | ximage->depth) == 1) && + (ximage->byte_order == ximage->bitmap_bit_order)) { + xoff = x + ximage->xoffset; + yoff = y * ximage->bytes_per_line + (xoff >> 3); + xoff &= 7; + if (ximage->bitmap_bit_order == MSBFirst) + bit = 0x80 >> xoff; + else + bit = 1 << xoff; + return (ximage->data[yoff] & bit) ? 1 : 0; + } else { + _XInitImageFuncPtrs(ximage); + return XGetPixel(ximage, x, y); + } +} + +/* + * PutPixel + * + * Overwrites the specified pixel. The X and Y coordinates are relative to + * the origin (upper left [0,0]) of the image. The input pixel value must be + * in normalized format, i.e. the LSB of the long is the LSB of the pixel. + * The algorithm used is: + * + * copy the destination bitmap_unit or Zpixel to temp + * normalize temp if needed + * copy the pixel bits into the temp + * renormalize temp if needed + * copy the temp back into the destination image data + * + */ + +static int _XPutPixel (ximage, x, y, pixel) + register XImage *ximage; + int x; + int y; + unsigned long pixel; + +{ + unsigned long px, npixel; + register char *src; + register char *dst; + register int i; + int j, nbytes; + long plane; + + if (ximage->depth == 4) + pixel &= 0xf; + npixel = pixel; + for (i=0, px=pixel; i<sizeof(unsigned long); i++, px>>=8) + ((unsigned char *)&pixel)[i] = px; + if ((ximage->bits_per_pixel | ximage->depth) == 1) { + src = &ximage->data[XYINDEX(x, y, ximage)]; + dst = (char *)&px; + px = 0; + nbytes = ximage->bitmap_unit >> 3; + for (i = nbytes; --i >= 0; ) *dst++ = *src++; + XYNORMALIZE(&px, ximage); + i = ((x + ximage->xoffset) % ximage->bitmap_unit); + _putbits ((char *)&pixel, i, 1, (char *)&px); + XYNORMALIZE(&px, ximage); + src = (char *) &px; + dst = &ximage->data[XYINDEX(x, y, ximage)]; + for (i = nbytes; --i >= 0; ) *dst++ = *src++; + } else if (ximage->format == XYPixmap) { + plane = (ximage->bytes_per_line * ximage->height) * + (ximage->depth - 1); /* do least signif plane 1st */ + nbytes = ximage->bitmap_unit >> 3; + for (j = ximage->depth; --j >= 0; ) { + src = &ximage->data[XYINDEX(x, y, ximage) + plane]; + dst = (char *) &px; + px = 0; + for (i = nbytes; --i >= 0; ) *dst++ = *src++; + XYNORMALIZE(&px, ximage); + i = ((x + ximage->xoffset) % ximage->bitmap_unit); + _putbits ((char *)&pixel, i, 1, (char *)&px); + XYNORMALIZE(&px, ximage); + src = (char *)&px; + dst = &ximage->data[XYINDEX(x, y, ximage) + plane]; + for (i = nbytes; --i >= 0; ) *dst++ = *src++; + npixel = npixel >> 1; + for (i=0, px=npixel; i<sizeof(unsigned long); i++, px>>=8) + ((unsigned char *)&pixel)[i] = px; + plane = plane - (ximage->bytes_per_line * ximage->height); + } + } else if (ximage->format == ZPixmap) { + src = &ximage->data[ZINDEX(x, y, ximage)]; + dst = (char *)&px; + px = 0; + nbytes = (ximage->bits_per_pixel + 7) >> 3; + for (i = nbytes; --i >= 0; ) *dst++ = *src++; + ZNORMALIZE(&px, ximage); + _putbits ((char *)&pixel, + (x * ximage->bits_per_pixel) & 7, + ximage->bits_per_pixel, (char *)&px); + ZNORMALIZE(&px, ximage); + src = (char *)&px; + dst = &ximage->data[ZINDEX(x, y, ximage)]; + for (i = nbytes; --i >= 0; ) *dst++ = *src++; + } else { + return 0; /* bad image */ + } + return 1; +} + +static int _XPutPixel32 (ximage, x, y, pixel) + register XImage *ximage; + int x; + int y; + unsigned long pixel; +{ + unsigned char *addr; + + if ((ximage->format == ZPixmap) && (ximage->bits_per_pixel == 32)) { + addr = &((unsigned char *)ximage->data) + [y * ximage->bytes_per_line + (x << 2)]; +#ifndef WORD64 + if (*((char *)&byteorderpixel) == ximage->byte_order) + *((CARD32 *)addr) = pixel; + else +#endif + if (ximage->byte_order == MSBFirst) { + addr[0] = pixel >> 24; + addr[1] = pixel >> 16; + addr[2] = pixel >> 8; + addr[3] = pixel; + } else { + addr[3] = pixel >> 24; + addr[2] = pixel >> 16; + addr[1] = pixel >> 8; + addr[0] = pixel; + } + return 1; + } else { + _XInitImageFuncPtrs(ximage); + return XPutPixel(ximage, x, y, pixel); + } +} + +static int _XPutPixel16 (ximage, x, y, pixel) + register XImage *ximage; + int x; + int y; + unsigned long pixel; +{ + unsigned char *addr; + + if ((ximage->format == ZPixmap) && (ximage->bits_per_pixel == 16)) { + addr = &((unsigned char *)ximage->data) + [y * ximage->bytes_per_line + (x << 1)]; + if (ximage->byte_order == MSBFirst) { + addr[0] = pixel >> 8; + addr[1] = pixel; + } else { + addr[1] = pixel >> 8; + addr[0] = pixel; + } + return 1; + } else { + _XInitImageFuncPtrs(ximage); + return XPutPixel(ximage, x, y, pixel); + } +} + +static int _XPutPixel8 (ximage, x, y, pixel) + register XImage *ximage; + int x; + int y; + unsigned long pixel; +{ + if ((ximage->format == ZPixmap) && (ximage->bits_per_pixel == 8)) { + ximage->data[y * ximage->bytes_per_line + x] = pixel; + return 1; + } else { + _XInitImageFuncPtrs(ximage); + return XPutPixel(ximage, x, y, pixel); + } +} + +static int _XPutPixel1 (ximage, x, y, pixel) + register XImage *ximage; + int x; + int y; + unsigned long pixel; +{ + unsigned char bit; + int xoff, yoff; + + if (((ximage->bits_per_pixel | ximage->depth) == 1) && + (ximage->byte_order == ximage->bitmap_bit_order)) { + xoff = x + ximage->xoffset; + yoff = y * ximage->bytes_per_line + (xoff >> 3); + xoff &= 7; + if (ximage->bitmap_bit_order == MSBFirst) + bit = 0x80 >> xoff; + else + bit = 1 << xoff; + if (pixel & 1) + ximage->data[yoff] |= bit; + else + ximage->data[yoff] &= ~bit; + return 1; + } else { + _XInitImageFuncPtrs(ximage); + return XPutPixel(ximage, x, y, pixel); + } +} + +/* + * SubImage + * + * Creates a new image that is a subsection of an existing one. + * Allocates the memory necessary for the new XImage data structure. + * Pointer to new image is returned. The algorithm used is repetitive + * calls to get and put pixel. + * + */ + +static XImage *_XSubImage (ximage, x, y, width, height) + XImage *ximage; + register int x; /* starting x coordinate in existing image */ + register int y; /* starting y coordinate in existing image */ + unsigned int width; /* width in pixels of new subimage */ + unsigned int height;/* height in pixels of new subimage */ + +{ + register XImage *subimage; + int dsize; + register int row, col; + register unsigned long pixel; + char *data; + + if ((subimage = (XImage *) Xcalloc (1, sizeof (XImage))) == NULL) + return (XImage *) NULL; + subimage->width = width; + subimage->height = height; + subimage->xoffset = 0; + subimage->format = ximage->format; + subimage->byte_order = ximage->byte_order; + subimage->bitmap_unit = ximage->bitmap_unit; + subimage->bitmap_bit_order = ximage->bitmap_bit_order; + subimage->bitmap_pad = ximage->bitmap_pad; + subimage->bits_per_pixel = ximage->bits_per_pixel; + subimage->depth = ximage->depth; + /* + * compute per line accelerator. + */ + if (subimage->format == ZPixmap) + subimage->bytes_per_line = + ROUNDUP(subimage->bits_per_pixel * width, + subimage->bitmap_pad); + else + subimage->bytes_per_line = + ROUNDUP(width, subimage->bitmap_pad); + subimage->obdata = NULL; + _XInitImageFuncPtrs (subimage); + dsize = subimage->bytes_per_line * height; + if (subimage->format == XYPixmap) dsize = dsize * subimage->depth; + if (((data = Xcalloc (1, (unsigned) dsize)) == NULL) && (dsize > 0)) { + Xfree((char *) subimage); + return (XImage *) NULL; + } + subimage->data = data; + + /* + * Test for cases where the new subimage is larger than the region + * that we are copying from the existing data. In those cases, + * copy the area of the existing image, and allow the "uncovered" + * area of new subimage to remain with zero filled pixels. + */ + if (height > ximage->height - y ) height = ximage->height - y; + if (width > ximage->width - x ) width = ximage->width - x; + + for (row = y; row < (y + height); row++) { + for (col = x; col < (x + width); col++) { + pixel = XGetPixel(ximage, col, row); + XPutPixel(subimage, (col - x), (row - y), pixel); + } + } + return subimage; +} + + +/* + * SetImage + * + * Overwrites a section of one image with all of the data from another. + * If the two images are not of the same format (i.e. XYPixmap and ZPixmap), + * the image data is converted to the destination format. The following + * restrictions apply: + * + * 1. The depths of the source and destination images must be equal. + * + * 2. If the height of the source image is too large to fit between + * the specified y starting point and the bottom of the image, + * then scanlines are truncated on the bottom. + * + * 3. If the width of the source image is too large to fit between + * the specified x starting point and the end of the scanline, + * then pixels are truncated on the right. + * + * The images need not have the same bitmap_bit_order, byte_order, + * bitmap_unit, bits_per_pixel, bitmap_pad, or xoffset. + * + */ + +int _XSetImage (srcimg, dstimg, x, y) + XImage *srcimg; + register XImage *dstimg; + register int x; + register int y; + +{ + register unsigned long pixel; + register int row, col; + int width, height, startrow, startcol; + if (x < 0) { + startcol = -x; + x = 0; + } else + startcol = 0; + if (y < 0) { + startrow = -y; + y = 0; + } else + startrow = 0; + width = dstimg->width - x; + if (srcimg->width < width) + width = srcimg->width; + height = dstimg->height - y; + if (srcimg->height < height) + height = srcimg->height; + + /* this is slow, will do better later */ + for (row = startrow; row < height; row++) { + for (col = startcol; col < width; col++) { + pixel = XGetPixel(srcimg, col, row); + XPutPixel(dstimg, x + col, y + row, pixel); + } + } + return 1; +} + +/* + * AddPixel + * + * Adds a constant value to every pixel in a pixmap. + * + */ + +static _XAddPixel (ximage, value) + register XImage *ximage; + register long value; +{ + register int x; + register int y; + + if (!value) + return 0; + if ((ximage->bits_per_pixel | ximage->depth) == 1) { + /* The only value that we can add here to an XYBitmap + * is one. Since 1 + value = ~value for one bit wide + * data, we do this quickly by taking the ones complement + * of the entire bitmap data (offset and pad included!). + * Note that we don't need to be concerned with bit or + * byte order at all. + */ + register unsigned char *dp = (unsigned char *) ximage->data; + x = ximage->bytes_per_line * ximage->height; + while (--x >= 0) { + *dp = ~*dp; + dp++; + } + } else if ((ximage->format == ZPixmap) && + (ximage->bits_per_pixel == 8)) { + register unsigned char *dp = (unsigned char *) ximage->data; + x = ximage->bytes_per_line * ximage->height; + while (--x >= 0) + *dp++ += value; +#ifndef WORD64 + } else if ((ximage->format == ZPixmap) && + (ximage->bits_per_pixel == 16) && + (*((char *)&byteorderpixel) == ximage->byte_order)) { + register unsigned short *dp = (unsigned short *) ximage->data; + x = (ximage->bytes_per_line >> 1) * ximage->height; + while (--x >= 0) + *dp++ += value; + } else if ((ximage->format == ZPixmap) && + (ximage->bits_per_pixel == 32) && + (*((char *)&byteorderpixel) == ximage->byte_order)) { + register CARD32 *dp = (CARD32 *) ximage->data; + x = (ximage->bytes_per_line >> 2) * ximage->height; + while (--x >= 0) + *dp++ += value; +#endif + } else { + for (y = ximage->height; --y >= 0; ) { + for (x = ximage->width; --x >= 0; ) { + register unsigned long pixel = XGetPixel(ximage, x, y); + pixel = pixel + value; + XPutPixel(ximage, x, y, pixel); + } + } + } + return 0; +} + diff --git a/src/InitExt.c b/src/InitExt.c new file mode 100644 index 00000000..c24d4490 --- /dev/null +++ b/src/InitExt.c @@ -0,0 +1,473 @@ +/* $Xorg: InitExt.c,v 1.4 2001/02/09 02:03:34 xorgcvs Exp $ */ +/* + +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. + +*/ + +#include <X11/Xlibint.h> +#include <X11/Xos.h> +#include <stdio.h> + +extern Bool _XUnknownWireEvent(); +extern Status _XUnknownNativeEvent(); +extern Bool _XDefaultWireError(); + +/* + * This routine is used to link a extension in so it will be called + * at appropriate times. + */ + +#if NeedFunctionPrototypes +XExtCodes *XInitExtension ( + Display *dpy, + _Xconst char *name) +#else +XExtCodes *XInitExtension (dpy, name) + Display *dpy; + char *name; +#endif +{ + XExtCodes codes; /* temp. place for extension information. */ + register _XExtension *ext;/* need a place to build it all */ + if (!XQueryExtension(dpy, name, + &codes.major_opcode, &codes.first_event, + &codes.first_error)) return (NULL); + + LockDisplay (dpy); + if (! (ext = (_XExtension *) Xcalloc (1, sizeof (_XExtension))) || + ! (ext->name = Xmalloc((unsigned) strlen(name) + 1))) { + if (ext) Xfree((char *) ext); + UnlockDisplay(dpy); + return (XExtCodes *) NULL; + } + codes.extension = dpy->ext_number++; + ext->codes = codes; + (void) strcpy(ext->name, name); + + /* chain it onto the display list */ + ext->next = dpy->ext_procs; + dpy->ext_procs = ext; + UnlockDisplay (dpy); + + return (&ext->codes); /* tell him which extension */ +} + +XExtCodes *XAddExtension (dpy) + Display *dpy; +{ + register _XExtension *ext; + + LockDisplay (dpy); + if (! (ext = (_XExtension *) Xcalloc (1, sizeof (_XExtension)))) { + UnlockDisplay(dpy); + return (XExtCodes *) NULL; + } + ext->codes.extension = dpy->ext_number++; + + /* chain it onto the display list */ + ext->next = dpy->ext_procs; + dpy->ext_procs = ext; + UnlockDisplay (dpy); + + return (&ext->codes); /* tell him which extension */ +} + +static _XExtension *XLookupExtension (dpy, extension) + register Display *dpy; /* display */ + register int extension; /* extension number */ +{ + register _XExtension *ext; + for (ext = dpy->ext_procs; ext; ext = ext->next) + if (ext->codes.extension == extension) return (ext); + return (NULL); +} + +XExtData **XEHeadOfExtensionList(object) + XEDataObject object; +{ + return *(XExtData ***)&object; +} + +XAddToExtensionList(structure, ext_data) + XExtData **structure; + XExtData *ext_data; +{ + ext_data->next = *structure; + *structure = ext_data; + return 1; +} + +XExtData *XFindOnExtensionList(structure, number) + XExtData **structure; + int number; +{ + XExtData *ext; + + ext = *structure; + while (ext && (ext->number != number)) + ext = ext->next; + return ext; +} + +typedef int (*CreateGCType) ( +#if NeedFunctionPrototypes + Display* /* display */, + GC /* gc */, + XExtCodes* /* codes */ +#endif +); + +/* + * Routines to hang procs on the extension structure. + */ +CreateGCType XESetCreateGC(dpy, extension, proc) + Display *dpy; /* display */ + int extension; /* extension number */ + CreateGCType proc; /* routine to call when GC created */ +{ + register _XExtension *e; /* for lookup of extension */ + register int (*oldproc)(); + if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL); + LockDisplay(dpy); + oldproc = e->create_GC; + e->create_GC = proc; + UnlockDisplay(dpy); + return (CreateGCType)oldproc; +} + +typedef int (*CopyGCType)( +#if NeedFunctionPrototypes + Display* /* display */, + GC /* gc */, + XExtCodes* /* codes */ +#endif +); + +CopyGCType XESetCopyGC(dpy, extension, proc) + Display *dpy; /* display */ + int extension; /* extension number */ + CopyGCType proc; /* routine to call when GC copied */ +{ + register _XExtension *e; /* for lookup of extension */ + register int (*oldproc)(); + if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL); + LockDisplay(dpy); + oldproc = e->copy_GC; + e->copy_GC = proc; + UnlockDisplay(dpy); + return (CopyGCType)oldproc; +} + +typedef int (*FlushGCType) ( +#if NeedFunctionPrototypes + Display* /* display */, + GC /* gc */, + XExtCodes* /* codes */ +#endif +); + +FlushGCType XESetFlushGC(dpy, extension, proc) + Display *dpy; /* display */ + int extension; /* extension number */ + FlushGCType proc; /* routine to call when GC copied */ +{ + register _XExtension *e; /* for lookup of extension */ + register int (*oldproc)(); + if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL); + LockDisplay(dpy); + oldproc = e->flush_GC; + e->flush_GC = proc; + UnlockDisplay(dpy); + return (FlushGCType)oldproc; +} + +typedef int (*FreeGCType) ( +#if NeedFunctionPrototypes + Display* /* display */, + GC /* gc */, + XExtCodes* /* codes */ +#endif +); + +FreeGCType XESetFreeGC(dpy, extension, proc) + Display *dpy; /* display */ + int extension; /* extension number */ + FreeGCType proc; /* routine to call when GC freed */ +{ + register _XExtension *e; /* for lookup of extension */ + register int (*oldproc)(); + if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL); + LockDisplay(dpy); + oldproc = e->free_GC; + e->free_GC = proc; + UnlockDisplay(dpy); + return (FreeGCType)oldproc; +} + +typedef int (*CreateFontType) ( +#if NeedFunctionPrototypes + Display* /* display */, + XFontStruct* /* fs */, + XExtCodes* /* codes */ +#endif +); + +CreateFontType XESetCreateFont(dpy, extension, proc) + Display *dpy; /* display */ + int extension; /* extension number */ + CreateFontType proc; /* routine to call when font created */ +{ + register _XExtension *e; /* for lookup of extension */ + register int (*oldproc)(); + if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL); + LockDisplay(dpy); + oldproc = e->create_Font; + e->create_Font = proc; + UnlockDisplay(dpy); + return (CreateFontType)oldproc; +} + +typedef int (*FreeFontType) ( +#if NeedFunctionPrototypes + Display* /* display */, + XFontStruct* /* fs */, + XExtCodes* /* codes */ +#endif +); + +FreeFontType XESetFreeFont(dpy, extension, proc) + Display *dpy; /* display */ + int extension; /* extension number */ + FreeFontType proc; /* routine to call when font freed */ +{ + register _XExtension *e; /* for lookup of extension */ + register int (*oldproc)(); + if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL); + LockDisplay(dpy); + oldproc = e->free_Font; + e->free_Font = proc; + UnlockDisplay(dpy); + return (FreeFontType)oldproc; +} + +typedef int (*CloseDisplayType) ( +#if NeedFunctionPrototypes + Display* /* display */, + XExtCodes* /* codes */ +#endif +); + +CloseDisplayType XESetCloseDisplay(dpy, extension, proc) + Display *dpy; /* display */ + int extension; /* extension number */ + CloseDisplayType proc; /* routine to call when display closed */ +{ + register _XExtension *e; /* for lookup of extension */ + register int (*oldproc)(); + if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL); + LockDisplay(dpy); + oldproc = e->close_display; + e->close_display = proc; + UnlockDisplay(dpy); + return (CloseDisplayType)oldproc; +} + +typedef Bool (*WireToEventType) ( +#if NeedFunctionPrototypes + Display* /* display */, + XEvent* /* re */, + xEvent* /* event */ +#endif +); + +WireToEventType XESetWireToEvent(dpy, event_number, proc) + Display *dpy; /* display */ + WireToEventType proc; /* routine to call when converting event */ + int event_number; /* event routine to replace */ +{ + register Bool (*oldproc)(); + if (proc == NULL) proc = (WireToEventType)_XUnknownWireEvent; + LockDisplay (dpy); + oldproc = dpy->event_vec[event_number]; + dpy->event_vec[event_number] = proc; + UnlockDisplay (dpy); + return (WireToEventType)oldproc; +} + +typedef Status (*EventToWireType) ( +#if NeedFunctionPrototypes + Display* /* display */, + XEvent* /* re */, + xEvent* /* event */ +#endif +); + +EventToWireType XESetEventToWire(dpy, event_number, proc) + Display *dpy; /* display */ + EventToWireType proc; /* routine to call when converting event */ + int event_number; /* event routine to replace */ +{ + register Status (*oldproc)(); + if (proc == NULL) proc = (EventToWireType) _XUnknownNativeEvent; + LockDisplay (dpy); + oldproc = dpy->wire_vec[event_number]; + dpy->wire_vec[event_number] = proc; + UnlockDisplay(dpy); + return (EventToWireType)oldproc; +} + +typedef Bool (*WireToErrorType) ( +#if NeedFunctionPrototypes + Display* /* display */, + XErrorEvent* /* he */, + xError* /* we */ +#endif +); + +WireToErrorType XESetWireToError(dpy, error_number, proc) + Display *dpy; /* display */ + WireToErrorType proc; /* routine to call when converting error */ + int error_number; /* error routine to replace */ +{ + register Bool (*oldproc)(); + if (proc == NULL) proc = (WireToErrorType)_XDefaultWireError; + LockDisplay (dpy); + if (!dpy->error_vec) { + int i; + dpy->error_vec = (Bool (**)())Xmalloc(256 * sizeof(oldproc)); + for (i = 1; i < 256; i++) + dpy->error_vec[i] = _XDefaultWireError; + } + if (dpy->error_vec) { + oldproc = dpy->error_vec[error_number]; + dpy->error_vec[error_number] = proc; + } + UnlockDisplay (dpy); + return (WireToErrorType)oldproc; +} + +typedef int (*ErrorType) ( +#if NeedFunctionPrototypes + Display* /* display */, + xError* /* err */, + XExtCodes* /* codes */, + int* /* ret_code */ +#endif +); + +ErrorType XESetError(dpy, extension, proc) + Display *dpy; /* display */ + int extension; /* extension number */ + ErrorType proc; /* routine to call when X error happens */ +{ + register _XExtension *e; /* for lookup of extension */ + register int (*oldproc)(); + if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL); + LockDisplay(dpy); + oldproc = e->error; + e->error = proc; + UnlockDisplay(dpy); + return (ErrorType)oldproc; +} + +typedef char* (*ErrorStringType) ( +#if NeedFunctionPrototypes + Display* /* display */, + int /* code */, + XExtCodes* /* codes */, + char* /* buffer */, + int /* nbytes */ +#endif +); + +ErrorStringType XESetErrorString(dpy, extension, proc) + Display *dpy; /* display */ + int extension; /* extension number */ + ErrorStringType proc; /* routine to call when I/O error happens */ +{ + register _XExtension *e; /* for lookup of extension */ + register char *(*oldproc)(); + if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL); + LockDisplay(dpy); + oldproc = e->error_string; + e->error_string = proc; + UnlockDisplay(dpy); + return (ErrorStringType)oldproc; +} + +typedef void (*PrintErrorType)( +#if NeedFunctionPrototypes + Display* /* display */, + XErrorEvent* /* ev */, + void* /* fp */ +#endif +); + +PrintErrorType XESetPrintErrorValues(dpy, extension, proc) + Display *dpy; /* display */ + int extension; /* extension number */ + PrintErrorType proc; /* routine to call to print */ +{ + register _XExtension *e; /* for lookup of extension */ + register void (*oldproc)(); + if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL); + LockDisplay(dpy); + oldproc = e->error_values; + e->error_values = proc; + UnlockDisplay(dpy); + return (PrintErrorType)oldproc; +} + +typedef void (*BeforeFlushType)( +#if NeedFunctionPrototypes + Display* /* display */, + XExtCodes* /* codes */, + char* /* data */, + long /* len */ +#endif +); + +BeforeFlushType XESetBeforeFlush(dpy, extension, proc) + Display *dpy; /* display */ + int extension; /* extension number */ + BeforeFlushType proc; /* routine to call on flush */ +{ + register _XExtension *e; /* for lookup of extension */ + register void (*oldproc)(); + register _XExtension *ext; + if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL); + LockDisplay(dpy); + oldproc = e->before_flush; + e->before_flush = proc; + for (ext = dpy->flushes; ext && ext != e; ext = ext->next) + ; + if (!ext) { + e->next_flush = dpy->flushes; + dpy->flushes = e; + } + UnlockDisplay(dpy); + return (BeforeFlushType)oldproc; +} diff --git a/src/InsCmap.c b/src/InsCmap.c new file mode 100644 index 00000000..1e10d953 --- /dev/null +++ b/src/InsCmap.c @@ -0,0 +1,41 @@ +/* $Xorg: InsCmap.c,v 1.4 2001/02/09 02:03:34 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XInstallColormap(dpy, cmap) +register Display *dpy; +Colormap cmap; +{ + register xResourceReq *req; + LockDisplay(dpy); + GetResReq(InstallColormap, cmap, req); + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} + diff --git a/src/IntAtom.c b/src/IntAtom.c new file mode 100644 index 00000000..467286b0 --- /dev/null +++ b/src/IntAtom.c @@ -0,0 +1,319 @@ +/* $Xorg: IntAtom.c,v 1.5 2001/02/09 02:03:34 xorgcvs Exp $ */ +/* + +Copyright 1986, 1990, 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. + +*/ + +#define NEED_REPLIES +#include "Xlibint.h" + +/* XXX this table def is duplicated in GetAtomNm.c, keep them consistent! */ + +#define TABLESIZE 64 + +typedef struct _Entry { + unsigned long sig; + Atom atom; +} EntryRec, *Entry; + +#define RESERVED ((Entry) 1) + +#define EntryName(e) ((char *)(e+1)) + +typedef struct _XDisplayAtoms { + Entry table[TABLESIZE]; +} AtomTable; + +#define HASH(sig) ((sig) & (TABLESIZE-1)) +#define REHASHVAL(sig) ((((sig) % (TABLESIZE-3)) + 2) | 1) +#define REHASH(idx,rehash) ((idx + rehash) & (TABLESIZE-1)) + +void +_XFreeAtomTable(dpy) + Display *dpy; +{ + register Entry *table; + register int i; + register Entry e; + + if (dpy->atoms) { + table = dpy->atoms->table; + for (i = TABLESIZE; --i >= 0; ) { + if ((e = *table++) && (e != RESERVED)) + Xfree((char *)e); + } + Xfree((char *)dpy->atoms); + } +} + +static +Atom _XInternAtom(dpy, name, onlyIfExists, psig, pidx, pn) + Display *dpy; + char *name; + Bool onlyIfExists; + unsigned long *psig; + int *pidx; + int *pn; +{ + register AtomTable *atoms; + register char *s1, c, *s2; + register unsigned long sig; + register int idx, i; + Entry e; + int n, firstidx, rehash; + xInternAtomReq *req; + + /* look in the cache first */ + if (!(atoms = dpy->atoms)) { + dpy->atoms = atoms = (AtomTable *)Xcalloc(1, sizeof(AtomTable)); + dpy->free_funcs->atoms = _XFreeAtomTable; + } + sig = 0; + for (s1 = (char *)name; (c = *s1++); ) + sig += c; + n = s1 - (char *)name - 1; + if (atoms) { + firstidx = idx = HASH(sig); + while ((e = atoms->table[idx])) { + if (e != RESERVED && e->sig == sig) { + for (i = n, s1 = (char *)name, s2 = EntryName(e); --i >= 0; ) { + if (*s1++ != *s2++) + goto nomatch; + } + if (!*s2) + return e->atom; + } +nomatch: if (idx == firstidx) + rehash = REHASHVAL(sig); + idx = REHASH(idx, rehash); + if (idx == firstidx) + break; + } + } + *psig = sig; + *pidx = idx; + if (atoms && !atoms->table[idx]) + atoms->table[idx] = RESERVED; /* reserve slot */ + *pn = n; + /* not found, go to the server */ + GetReq(InternAtom, req); + req->nbytes = n; + req->onlyIfExists = onlyIfExists; + req->length += (n+3)>>2; + Data(dpy, name, n); + return None; +} + +void +_XUpdateAtomCache(dpy, name, atom, sig, idx, n) + Display *dpy; + char *name; + Atom atom; + unsigned long sig; + int idx; + int n; +{ + Entry e, oe; + register char *s1; + register char c; + int firstidx, rehash; + + if (!dpy->atoms) { + if (idx < 0) { + dpy->atoms = (AtomTable *)Xcalloc(1, sizeof(AtomTable)); + dpy->free_funcs->atoms = _XFreeAtomTable; + } + if (!dpy->atoms) + return; + } + if (!sig) { + for (s1 = (char *)name; (c = *s1++); ) + sig += c; + n = s1 - (char *)name - 1; + if (idx < 0) { + firstidx = idx = HASH(sig); + if (dpy->atoms->table[idx]) { + rehash = REHASHVAL(sig); + do + idx = REHASH(idx, rehash); + while (idx != firstidx && dpy->atoms->table[idx]); + } + } + } + e = (Entry)Xmalloc(sizeof(EntryRec) + n + 1); + if (e) { + e->sig = sig; + e->atom = atom; + strcpy(EntryName(e), name); + if ((oe = dpy->atoms->table[idx]) && (oe != RESERVED)) + Xfree((char *)oe); + dpy->atoms->table[idx] = e; + } +} + +#if NeedFunctionPrototypes +Atom XInternAtom ( + Display *dpy, + _Xconst char *name, + Bool onlyIfExists) +#else +Atom XInternAtom (dpy, name, onlyIfExists) + Display *dpy; + char *name; + Bool onlyIfExists; +#endif +{ + Atom atom; + unsigned long sig; + int idx, n; + xInternAtomReply rep; + + if (!name) + name = ""; + LockDisplay(dpy); + if ((atom = _XInternAtom(dpy, name, onlyIfExists, &sig, &idx, &n))) { + UnlockDisplay(dpy); + return atom; + } + if (dpy->atoms && dpy->atoms->table[idx] == RESERVED) + dpy->atoms->table[idx] = NULL; /* unreserve slot */ + if (_XReply (dpy, (xReply *)&rep, 0, xTrue)) { + if ((atom = rep.atom)) + _XUpdateAtomCache(dpy, name, atom, sig, idx, n); + } + UnlockDisplay(dpy); + SyncHandle(); + return (rep.atom); +} + +typedef struct { + unsigned long start_seq; + unsigned long stop_seq; + char **names; + Atom *atoms; + int count; + Status status; +} _XIntAtomState; + +static +Bool _XIntAtomHandler(dpy, rep, buf, len, data) + register Display *dpy; + register xReply *rep; + char *buf; + int len; + XPointer data; +{ + register _XIntAtomState *state; + register int i, idx; + xInternAtomReply replbuf; + register xInternAtomReply *repl; + + state = (_XIntAtomState *)data; + if (dpy->last_request_read < state->start_seq || + dpy->last_request_read > state->stop_seq) + return False; + for (i = 0; i < state->count; i++) { + if (state->atoms[i] & 0x80000000) { + idx = ~state->atoms[i]; + state->atoms[i] = None; + break; + } + } + if (i >= state->count) + return False; + if (rep->generic.type == X_Error) { + state->status = 0; + return False; + } + repl = (xInternAtomReply *) + _XGetAsyncReply(dpy, (char *)&replbuf, rep, buf, len, + (SIZEOF(xInternAtomReply) - SIZEOF(xReply)) >> 2, + True); + if ((state->atoms[i] = repl->atom)) + _XUpdateAtomCache(dpy, state->names[i], (Atom) repl->atom, + (unsigned long)0, idx, 0); + return True; +} + +Status +XInternAtoms (dpy, names, count, onlyIfExists, atoms_return) + Display *dpy; + char **names; + int count; + Bool onlyIfExists; + Atom *atoms_return; +{ + int i, idx, n, tidx; + unsigned long sig; + _XAsyncHandler async; + _XIntAtomState async_state; + int missed = -1; + xInternAtomReply rep; + + LockDisplay(dpy); + async_state.start_seq = dpy->request + 1; + async_state.atoms = atoms_return; + async_state.names = names; + async_state.count = count - 1; + async_state.status = 1; + async.next = dpy->async_handlers; + async.handler = _XIntAtomHandler; + async.data = (XPointer)&async_state; + dpy->async_handlers = &async; + for (i = 0; i < count; i++) { + if (!(atoms_return[i] = _XInternAtom(dpy, names[i], onlyIfExists, + &sig, &idx, &n))) { + missed = i; + atoms_return[i] = ~((Atom)idx); + async_state.stop_seq = dpy->request; + } + } + if (missed >= 0) { + if (dpy->atoms) { + /* unreserve anything we just reserved */ + for (i = 0; i < count; i++) { + if (atoms_return[i] & 0x80000000) { + tidx = ~atoms_return[i]; + if (dpy->atoms->table[tidx] == RESERVED) + dpy->atoms->table[tidx] = NULL; + } + } + } + if (_XReply (dpy, (xReply *)&rep, 0, xTrue)) { + if ((atoms_return[missed] = rep.atom)) + _XUpdateAtomCache(dpy, names[missed], (Atom) rep.atom, + sig, idx, n); + } else { + atoms_return[missed] = None; + async_state.status = 0; + } + } + DeqAsyncHandler(dpy, &async); + UnlockDisplay(dpy); + if (missed >= 0) + SyncHandle(); + return async_state.status; +} diff --git a/src/KeyBind.c b/src/KeyBind.c new file mode 100644 index 00000000..f56a06a4 --- /dev/null +++ b/src/KeyBind.c @@ -0,0 +1,731 @@ +/* $Xorg: KeyBind.c,v 1.4 2001/02/09 02:03:34 xorgcvs Exp $ */ +/* + +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 */ + +#define NEED_EVENTS +#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_CYRILLIC +#define XK_GREEK +#define XK_XKB_KEYS +#include <X11/keysymdef.h> +#include <stdio.h> + +#ifdef USE_OWN_COMPOSE +#include "imComp.h" +#endif + +#ifdef XKB +#define XKeycodeToKeysym _XKeycodeToKeysym +#define XKeysymToKeycode _XKeysymToKeycode +#define XLookupKeysym _XLookupKeysym +#define XRefreshKeyboardMapping _XRefreshKeyboardMapping +#define XLookupString _XLookupString +#else +#define XkbKeysymToModifiers _XKeysymToModifiers +#endif + +#define AllMods (ShiftMask|LockMask|ControlMask| \ + Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask) + +static void ComputeMaskFromKeytrans(); + +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 +#if NeedFunctionPrototypes +KeyCodetoKeySym(register Display *dpy, KeyCode keycode, int col) +#else +KeyCodetoKeySym(dpy, keycode, col) + register Display *dpy; + KeyCode keycode; + int col; +#endif +{ + 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]; +} + +#if NeedFunctionPrototypes +KeySym +XKeycodeToKeysym(Display *dpy, +#if NeedWidePrototypes + unsigned int kc, +#else + KeyCode kc, +#endif + int col) +#else +KeySym +XKeycodeToKeysym(dpy, kc, col) + Display *dpy; + KeyCode kc; + int col; +#endif +{ + if ((! dpy->keysyms) && (! _XKeyInitialize(dpy))) + return NoSymbol; + return KeyCodetoKeySym(dpy, kc, col); +} + +KeyCode +XKeysymToKeycode(dpy, ks) + 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(event, col) + register XKeyEvent *event; + int col; +{ + if ((! event->display->keysyms) && (! _XKeyInitialize(event->display))) + return NoSymbol; + return KeyCodetoKeySym(event->display, event->keycode, col); +} + +static void +ResetModMap(dpy) + 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(dpy) + 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; +} + +XRefreshKeyboardMapping(event) + 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(dpy) + 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; +} + +void +XConvertCase(sym, lower, upper) + register KeySym sym; + KeySym *lower; + KeySym *upper; +{ + *lower = sym; + *upper = sym; + switch(sym >> 8) { + case 0: /* Latin 1 */ + if ((sym >= XK_A) && (sym <= XK_Z)) + *lower += (XK_a - XK_A); + else if ((sym >= XK_a) && (sym <= XK_z)) + *upper -= (XK_a - XK_A); + else if ((sym >= XK_Agrave) && (sym <= XK_Odiaeresis)) + *lower += (XK_agrave - XK_Agrave); + else if ((sym >= XK_agrave) && (sym <= XK_odiaeresis)) + *upper -= (XK_agrave - XK_Agrave); + else if ((sym >= XK_Ooblique) && (sym <= XK_Thorn)) + *lower += (XK_oslash - XK_Ooblique); + else if ((sym >= XK_oslash) && (sym <= XK_thorn)) + *upper -= (XK_oslash - XK_Ooblique); + break; + 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; + } +} + +int +#if NeedFunctionPrototypes +_XTranslateKey( register Display *dpy, + KeyCode keycode, + register unsigned int modifiers, + unsigned int *modifiers_return, + KeySym *keysym_return) +#else +_XTranslateKey(dpy, keycode, modifiers, modifiers_return, keysym_return) + register Display *dpy; + KeyCode keycode; + register unsigned int modifiers; + unsigned int *modifiers_return; + KeySym *keysym_return; +#endif +{ + 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(dpy, symbol, modifiers, buffer, nbytes) + 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 (event, buffer, nbytes, keysym, status) + 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 (dpy) + 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); + } +} + +#if NeedFunctionPrototypes +XRebindKeysym ( + Display *dpy, + KeySym keysym, + KeySym *mlist, + int nm, /* number of modifiers in mlist */ + _Xconst unsigned char *str, + int nbytes) +#else +XRebindKeysym (dpy, keysym, mlist, nm, str, nbytes) + Display *dpy; + KeySym keysym; + KeySym *mlist; + int nm; /* number of modifiers in mlist */ + unsigned char *str; + int nbytes; +#endif +{ + 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 *) Xmalloc( 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(dpy,ks) + 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(dpy, p) + 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/src/KeysymStr.c b/src/KeysymStr.c new file mode 100644 index 00000000..1e94a5d7 --- /dev/null +++ b/src/KeysymStr.c @@ -0,0 +1,137 @@ +/* $Xorg: KeysymStr.c,v 1.5 2001/02/09 02:03:34 xorgcvs Exp $ */ + +/* + +Copyright 1990, 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. + +*/ + +#include "Xlibint.h" +#include <X11/Xresource.h> +#include <X11/keysymdef.h> + +#ifdef __STDC__ +#define Const const +#else +#define Const /**/ +#endif + +typedef unsigned long Signature; + +#define NEEDVTABLE +#include "ks_tables.h" + +extern XrmDatabase _XInitKeysymDB(); +extern Const unsigned char _XkeyTable[]; + + +typedef struct _GRNData { + char *name; + XrmRepresentation type; + XrmValuePtr value; +} GRNData; + +#if NeedFunctionPrototypes +/*ARGSUSED*/ +static Bool SameValue( + XrmDatabase* db, + XrmBindingList bindings, + XrmQuarkList quarks, + XrmRepresentation* type, + XrmValuePtr value, + XPointer data +) +#else +static Bool SameValue(db, bindings, quarks, type, value, data) + XrmDatabase *db; + XrmBindingList bindings; + XrmQuarkList quarks; + XrmRepresentation *type; + XrmValuePtr value; + XPointer data; +#endif +{ + GRNData *gd = (GRNData *)data; + + if ((*type == gd->type) && (value->size == gd->value->size) && + !strncmp((char *)value->addr, (char *)gd->value->addr, value->size)) + { + gd->name = XrmQuarkToString(*quarks); /* XXX */ + return True; + } + return False; +} + +char *XKeysymToString(ks) + KeySym ks; +{ + register int i, n; + int h; + register int idx; + Const unsigned char *entry; + unsigned char val1, val2; + XrmDatabase keysymdb; + + if (!ks || (ks & ((unsigned long) ~0x1fffffff)) != 0) + return ((char *)NULL); + if (ks == XK_VoidSymbol) + ks = 0; + if (ks <= 0xffff) + { + val1 = ks >> 8; + val2 = ks & 0xff; + i = ks % VTABLESIZE; + h = i + 1; + n = VMAXHASH; + while ((idx = hashKeysym[i])) + { + entry = &_XkeyTable[idx]; + if ((entry[0] == val1) && (entry[1] == val2)) + return ((char *)entry + 2); + if (!--n) + break; + i += h; + if (i >= VTABLESIZE) + i -= VTABLESIZE; + } + } + + if ((keysymdb = _XInitKeysymDB())) + { + char buf[9]; + XrmValue resval; + XrmQuark empty = NULLQUARK; + GRNData data; + + sprintf(buf, "%lX", ks); + resval.addr = (XPointer)buf; + resval.size = strlen(buf) + 1; + data.name = (char *)NULL; + data.type = XrmPermStringToQuark("String"); + data.value = &resval; + (void)XrmEnumerateDatabase(keysymdb, &empty, &empty, XrmEnumAllLevels, + SameValue, (XPointer)&data); + return data.name; + } + return ((char *) NULL); +} diff --git a/src/KillCl.c b/src/KillCl.c new file mode 100644 index 00000000..750ea825 --- /dev/null +++ b/src/KillCl.c @@ -0,0 +1,41 @@ +/* $Xorg: KillCl.c,v 1.4 2001/02/09 02:03:34 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XKillClient(dpy, resource) + register Display *dpy; + XID resource; +{ + register xResourceReq *req; + LockDisplay(dpy); + GetResReq(KillClient, resource, req); + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} + diff --git a/src/LiHosts.c b/src/LiHosts.c new file mode 100644 index 00000000..2f22d71d --- /dev/null +++ b/src/LiHosts.c @@ -0,0 +1,100 @@ +/* $Xorg: LiHosts.c,v 1.4 2001/02/09 02:03:34 xorgcvs Exp $ */ +/* + +Copyright 1986, 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 can really be considered an os dependent routine */ + +#define NEED_REPLIES +#include "Xlibint.h" +/* + * can be freed using XFree. + */ + +XHostAddress *XListHosts (dpy, nhosts, enabled) + register Display *dpy; + int *nhosts; /* RETURN */ + Bool *enabled; /* RETURN */ + { + register XHostAddress *outbuf = 0, *op; + xListHostsReply reply; + long nbytes; + unsigned char *buf, *bp; + register unsigned i; + register xListHostsReq *req; + + *nhosts = 0; + LockDisplay(dpy); + GetReq (ListHosts, req); + + if (!_XReply (dpy, (xReply *) &reply, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return (XHostAddress *) NULL; + } + + if (reply.nHosts) { + nbytes = reply.length << 2; /* compute number of bytes in reply */ + op = outbuf = (XHostAddress *) + Xmalloc((unsigned) (nbytes + reply.nHosts * sizeof(XHostAddress))); + + if (! outbuf) { + _XEatData(dpy, (unsigned long) nbytes); + UnlockDisplay(dpy); + SyncHandle(); + return (XHostAddress *) NULL; + } + bp = buf = + ((unsigned char *) outbuf) + reply.nHosts * sizeof(XHostAddress); + + _XRead (dpy, (char *) buf, nbytes); + + for (i = 0; i < reply.nHosts; i++) { +#ifdef WORD64 + xHostEntry xhe; + memcpy((char *)&xhe, bp, SIZEOF(xHostEntry)); + op->family = xhe.family; + op->length = xhe.length; +#else + op->family = ((xHostEntry *) bp)->family; + op->length =((xHostEntry *) bp)->length; +#endif + op->address = (char *) (bp + SIZEOF(xHostEntry)); + bp += SIZEOF(xHostEntry) + (((op->length + 3) >> 2) << 2); + op++; + } + } + + *enabled = reply.enabled; + *nhosts = reply.nHosts; + UnlockDisplay(dpy); + SyncHandle(); + return (outbuf); +} + + + + + diff --git a/src/LiICmaps.c b/src/LiICmaps.c new file mode 100644 index 00000000..93076cc7 --- /dev/null +++ b/src/LiICmaps.c @@ -0,0 +1,70 @@ +/* $Xorg: LiICmaps.c,v 1.4 2001/02/09 02:03:34 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#define NEED_REPLIES +#include "Xlibint.h" + +Colormap *XListInstalledColormaps(dpy, win, n) +register Display *dpy; +Window win; +int *n; /* RETURN */ +{ + long nbytes; + Colormap *cmaps; + xListInstalledColormapsReply rep; + register xResourceReq *req; + + LockDisplay(dpy); + GetResReq(ListInstalledColormaps, win, req); + + if(_XReply(dpy, (xReply *) &rep, 0, xFalse) == 0) { + UnlockDisplay(dpy); + SyncHandle(); + *n = 0; + return((Colormap *) NULL); + } + + if (rep.nColormaps) { + nbytes = rep.nColormaps * sizeof(Colormap); + cmaps = (Colormap *) Xmalloc((unsigned) nbytes); + nbytes = rep.nColormaps << 2; + if (! cmaps) { + _XEatData(dpy, (unsigned long) nbytes); + UnlockDisplay(dpy); + SyncHandle(); + return((Colormap *) NULL); + } + _XRead32 (dpy, (char *) cmaps, nbytes); + } + else cmaps = (Colormap *) NULL; + + *n = rep.nColormaps; + UnlockDisplay(dpy); + SyncHandle(); + return(cmaps); +} + diff --git a/src/LiProps.c b/src/LiProps.c new file mode 100644 index 00000000..ae733d74 --- /dev/null +++ b/src/LiProps.c @@ -0,0 +1,68 @@ +/* $Xorg: LiProps.c,v 1.4 2001/02/09 02:03:34 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#define NEED_REPLIES +#include "Xlibint.h" + +Atom *XListProperties(dpy, window, n_props) +register Display *dpy; +Window window; +int *n_props; /* RETURN */ +{ + long nbytes; + xListPropertiesReply rep; + Atom *properties; + register xResourceReq *req; + + LockDisplay(dpy); + GetResReq(ListProperties, window, req); + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + *n_props = 0; + UnlockDisplay(dpy); + SyncHandle(); + return ((Atom *) NULL); + } + + if (rep.nProperties) { + nbytes = rep.nProperties * sizeof(Atom); + properties = (Atom *) Xmalloc ((unsigned) nbytes); + nbytes = rep.nProperties << 2; + if (! properties) { + _XEatData(dpy, (unsigned long) nbytes); + UnlockDisplay(dpy); + SyncHandle(); + return (Atom *) NULL; + } + _XRead32 (dpy, (char *) properties, nbytes); + } + else properties = (Atom *) NULL; + + *n_props = rep.nProperties; + UnlockDisplay(dpy); + SyncHandle(); + return (properties); +} diff --git a/src/ListExt.c b/src/ListExt.c new file mode 100644 index 00000000..6d626be9 --- /dev/null +++ b/src/ListExt.c @@ -0,0 +1,96 @@ +/* $Xorg: ListExt.c,v 1.4 2001/02/09 02:03:34 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#define NEED_REPLIES +#include "Xlibint.h" + +char **XListExtensions(dpy, nextensions) +register Display *dpy; +int *nextensions; /* RETURN */ +{ + xListExtensionsReply rep; + char **list; + char *ch; + register unsigned i; + register int length; + register xReq *req; + register long rlen; + + LockDisplay(dpy); + GetEmptyReq (ListExtensions, req); + + if (! _XReply (dpy, (xReply *) &rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return (char **) NULL; + } + + if (rep.nExtensions) { + list = (char **) Xmalloc ( + (unsigned)(rep.nExtensions * sizeof (char *))); + rlen = rep.length << 2; + ch = (char *) Xmalloc ((unsigned) rlen + 1); + /* +1 to leave room for last null-terminator */ + + if ((!list) || (!ch)) { + if (list) Xfree((char *) list); + if (ch) Xfree((char *) ch); + _XEatData(dpy, (unsigned long) rlen); + UnlockDisplay(dpy); + SyncHandle(); + return (char **) NULL; + } + + _XReadPad (dpy, ch, rlen); + /* + * unpack into null terminated strings. + */ + length = *ch; + for (i = 0; i < rep.nExtensions; i++) { + list[i] = ch+1; /* skip over length */ + ch += length + 1; /* find next length ... */ + length = *ch; + *ch = '\0'; /* and replace with null-termination */ + } + } + else list = (char **) NULL; + + *nextensions = rep.nExtensions; + UnlockDisplay(dpy); + SyncHandle(); + return (list); +} + +XFreeExtensionList (list) +char **list; +{ + if (list != NULL) { + Xfree (list[0]-1); + Xfree ((char *)list); + } + return 1; +} diff --git a/src/LoadFont.c b/src/LoadFont.c new file mode 100644 index 00000000..6dd96ad6 --- /dev/null +++ b/src/LoadFont.c @@ -0,0 +1,54 @@ +/* $Xorg: LoadFont.c,v 1.4 2001/02/09 02:03:34 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +#if NeedFunctionPrototypes +Font XLoadFont ( + register Display *dpy, + _Xconst char *name) +#else +Font XLoadFont (dpy, name) + register Display *dpy; + char *name; +#endif +{ + register long nbytes; + Font fid; + register xOpenFontReq *req; + LockDisplay(dpy); + GetReq(OpenFont, req); + nbytes = req->nbytes = name ? strlen(name) : 0; + req->fid = fid = XAllocID(dpy); + req->length += (nbytes+3)>>2; + Data (dpy, name, nbytes); + UnlockDisplay(dpy); + SyncHandle(); + return (fid); + /* can't return (req->fid) since request may have already been sent */ +} + diff --git a/src/LockDis.c b/src/LockDis.c new file mode 100644 index 00000000..91766791 --- /dev/null +++ b/src/LockDis.c @@ -0,0 +1,90 @@ +/* $Xorg: LockDis.c,v 1.4 2001/02/09 02:03:34 xorgcvs Exp $ */ + +/* + +Copyright 1993, 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. + +*/ + +/* + * Author: Stephen Gildea, MIT X Consortium + * + * XLockDis.c - multi-thread application-level locking routines + */ + +#include "Xlibint.h" +#ifdef XTHREADS +#include "locking.h" +#endif + +#if NeedFunctionPrototypes +void XLockDisplay( + register Display* dpy) +#else +void XLockDisplay(dpy) + register Display* dpy; +#endif +{ +#ifdef XTHREADS + LockDisplay(dpy); + if (dpy->lock) + (*dpy->lock->user_lock_display)(dpy); + /* + * We want the threads in the reply queue to all get out before + * XLockDisplay returns, in case they have any side effects the + * caller of XLockDisplay was trying to protect against. + * XLockDisplay puts itself at the head of the event waiters queue + * to wait for all the replies to come in. + */ + if (dpy->lock && dpy->lock->reply_awaiters) { + struct _XCVList *cvl; + + cvl = (*dpy->lock->create_cvl)(dpy); + + /* stuff ourselves on the head of the queue */ + cvl->next = dpy->lock->event_awaiters; + dpy->lock->event_awaiters = cvl; + + while (dpy->lock->reply_awaiters) + ConditionWait(dpy, cvl->cv); + UnlockNextEventReader(dpy); /* pass the signal on */ + } + UnlockDisplay(dpy); +#endif +} + +#if NeedFunctionPrototypes +void XUnlockDisplay( + register Display* dpy) +#else +void XUnlockDisplay(dpy) + register Display* dpy; +#endif +{ +#ifdef XTHREADS + LockDisplay(dpy); + if (dpy->lock) + (*dpy->lock->user_unlock_display)(dpy); + UnlockDisplay(dpy); +#endif +} diff --git a/src/LookupCol.c b/src/LookupCol.c new file mode 100644 index 00000000..b7f56d3d --- /dev/null +++ b/src/LookupCol.c @@ -0,0 +1,104 @@ +/* $Xorg: LookupCol.c,v 1.4 2001/02/09 02:03:34 xorgcvs Exp $ */ +/* + +Copyright 1985, 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. + +*/ + +#define NEED_REPLIES +#include <stdio.h> +#include "Xlibint.h" +#include "Xcmsint.h" + +extern void _XcmsRGB_to_XColor(); +extern void _XUnresolveColor(); + +#if NeedFunctionPrototypes +Status XLookupColor ( + register Display *dpy, + Colormap cmap, + _Xconst char *spec, + XColor *def, + XColor *scr) +#else +Status XLookupColor (dpy, cmap, spec, def, scr) + register Display *dpy; + Colormap cmap; + char *spec; + XColor *def, *scr; +#endif +{ + register int n; + xLookupColorReply reply; + register xLookupColorReq *req; + XcmsCCC ccc; + XcmsColor cmsColor_exact; + + /* + * Let's Attempt to use Xcms and i18n approach to Parse Color + */ + /* copy string to allow overwrite by _XcmsResolveColorString() */ + if ((ccc = XcmsCCCOfColormap(dpy, cmap)) != (XcmsCCC)NULL) { + if (_XcmsResolveColorString(ccc, &spec, + &cmsColor_exact, XcmsRGBFormat) >= XcmsSuccess) { + _XcmsRGB_to_XColor(&cmsColor_exact, def, 1); + memcpy((char *)scr, (char *)def, sizeof(XColor)); + _XUnresolveColor(ccc, scr); + return(1); + } + /* + * Otherwise we failed; or spec was changed with yet another + * name. Thus pass name to the X Server. + */ + } + + + /* + * Xcms and i18n methods failed, so lets pass it to the server + * for parsing. + */ + + n = strlen (spec); + LockDisplay(dpy); + GetReq (LookupColor, req); + req->cmap = cmap; + req->nbytes = n; + req->length += (n + 3) >> 2; + Data (dpy, spec, (long)n); + if (!_XReply (dpy, (xReply *) &reply, 0, xTrue)) { + UnlockDisplay(dpy); + SyncHandle(); + return (0); + } + def->red = reply.exactRed; + def->green = reply.exactGreen; + def->blue = reply.exactBlue; + + scr->red = reply.screenRed; + scr->green = reply.screenGreen; + scr->blue = reply.screenBlue; + + UnlockDisplay(dpy); + SyncHandle(); + return (1); +} diff --git a/src/LowerWin.c b/src/LowerWin.c new file mode 100644 index 00000000..fb53df0a --- /dev/null +++ b/src/LowerWin.c @@ -0,0 +1,46 @@ +/* $Xorg: LowerWin.c,v 1.4 2001/02/09 02:03:34 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XLowerWindow(dpy, w) +Display *dpy; +Window w; +{ + register xConfigureWindowReq *req; + unsigned long val = Below; /* needed for macro */ + + LockDisplay(dpy); + GetReqExtra(ConfigureWindow, 4, req); + req->window = w; + req->mask = CWStackMode; + OneDataCard32 (dpy, NEXTPTR(req,xConfigureWindowReq), val); + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} + diff --git a/src/Macros.c b/src/Macros.c new file mode 100644 index 00000000..61188588 --- /dev/null +++ b/src/Macros.c @@ -0,0 +1,250 @@ +/* $Xorg: Macros.c,v 1.4 2001/02/09 02:03:34 xorgcvs Exp $ */ +/* + +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. + +*/ + +#include "Xlibint.h" +/* + * This file makes full definitions of routines for each macro. + * We do not expect C programs to use these, but other languages may + * need them. + */ + +int XConnectionNumber(dpy) Display *dpy; { return (ConnectionNumber(dpy)); } + +Window XRootWindow (dpy, scr) + Display *dpy; int scr; + { return (RootWindow(dpy,scr)); } + +int XDefaultScreen(dpy) Display *dpy; { return (DefaultScreen(dpy)); } + +Window XDefaultRootWindow (dpy) + Display *dpy; + { return (RootWindow(dpy,DefaultScreen(dpy))); } + +Visual *XDefaultVisual(dpy, scr) + Display *dpy; int scr; + { return (DefaultVisual(dpy, scr)); } + +GC XDefaultGC(dpy, scr) + Display *dpy; int scr; + { return (DefaultGC(dpy,scr)); } + +unsigned long XBlackPixel(dpy, scr) + Display *dpy; int scr; + { return (BlackPixel(dpy, scr)); } + +unsigned long XWhitePixel(dpy, scr) + Display *dpy; int scr; + { return (WhitePixel(dpy,scr)); } + +unsigned long XAllPlanes() { return AllPlanes; } + +int XQLength(dpy) Display *dpy; { return (QLength(dpy)); } + +int XDisplayWidth(dpy, scr) + Display *dpy; int scr; + { return (DisplayWidth(dpy,scr)); } + +int XDisplayHeight(dpy, scr) + Display *dpy; int scr; + { return (DisplayHeight(dpy, scr)); } + +int XDisplayWidthMM(dpy, scr) + Display *dpy; int scr; + { return (DisplayWidthMM(dpy, scr)); } + +int XDisplayHeightMM(dpy, scr) + Display *dpy; int scr; + { return (DisplayHeightMM(dpy, scr)); } + +int XDisplayPlanes(dpy, scr) + Display *dpy; int scr; + { return (DisplayPlanes(dpy, scr)); } + +int XDisplayCells(dpy, scr) + Display *dpy; int scr; + { return (DisplayCells (dpy, scr)); } + +int XScreenCount(dpy) Display *dpy; { return (ScreenCount(dpy)); } + +char *XServerVendor(dpy) Display *dpy; { return (ServerVendor(dpy)); } + +int XProtocolVersion(dpy) Display *dpy; { return (ProtocolVersion(dpy)); } + +int XProtocolRevision(dpy) Display *dpy; { return (ProtocolRevision(dpy));} + +int XVendorRelease(dpy) Display *dpy; { return (VendorRelease(dpy)); } + +char *XDisplayString(dpy) Display *dpy; { return (DisplayString(dpy)); } + +int XDefaultDepth(dpy, scr) + Display *dpy; int scr; + { return(DefaultDepth(dpy, scr)); } + +Colormap XDefaultColormap(dpy, scr) + Display *dpy; int scr; + { return (DefaultColormap(dpy, scr)); } + +int XBitmapUnit(dpy) Display *dpy; { return (BitmapUnit(dpy)); } + +int XBitmapBitOrder(dpy) Display *dpy; { return (BitmapBitOrder(dpy)); } + +int XBitmapPad(dpy) Display *dpy; { return (BitmapPad(dpy)); } + +int XImageByteOrder(dpy) Display *dpy; { return (ImageByteOrder(dpy)); } + +unsigned long XNextRequest(dpy) + Display *dpy; + { +#ifdef WORD64 + WORD64ALIGN + return dpy->request + 1; +#else + return (NextRequest(dpy)); +#endif + } + +unsigned long XLastKnownRequestProcessed(dpy) + Display *dpy; + { return (LastKnownRequestProcessed(dpy)); } + +/* screen oriented macros (toolkit) */ +Screen *XScreenOfDisplay(dpy, scr) Display *dpy; int scr; + { return (ScreenOfDisplay(dpy, scr)); } + +Screen *XDefaultScreenOfDisplay(dpy) Display *dpy; + { return (DefaultScreenOfDisplay(dpy)); } + +Display *XDisplayOfScreen(s) Screen *s; { return (DisplayOfScreen(s)); } + +Window XRootWindowOfScreen(s) Screen *s; { return (RootWindowOfScreen(s)); } + +unsigned long XBlackPixelOfScreen(s) Screen *s; + { return (BlackPixelOfScreen(s)); } + +unsigned long XWhitePixelOfScreen(s) Screen *s; + { return (WhitePixelOfScreen(s)); } + +Colormap XDefaultColormapOfScreen(s) Screen *s; + { return (DefaultColormapOfScreen(s)); } + +int XDefaultDepthOfScreen(s) Screen *s; { return (DefaultDepthOfScreen(s)); } + +GC XDefaultGCOfScreen(s) Screen *s; { return (DefaultGCOfScreen(s)); } + +Visual *XDefaultVisualOfScreen(s) Screen *s; + { return (DefaultVisualOfScreen(s)); } + +int XWidthOfScreen(s) Screen *s; { return (WidthOfScreen(s)); } + +int XHeightOfScreen(s) Screen *s; { return (HeightOfScreen(s)); } + +int XWidthMMOfScreen(s) Screen *s; { return (WidthMMOfScreen(s)); } + +int XHeightMMOfScreen(s) Screen *s; { return (HeightMMOfScreen(s)); } + +int XPlanesOfScreen(s) Screen *s; { return (PlanesOfScreen(s)); } + +int XCellsOfScreen(s) Screen *s; { return (CellsOfScreen(s)); } + +int XMinCmapsOfScreen(s) Screen *s; { return (MinCmapsOfScreen(s)); } + +int XMaxCmapsOfScreen(s) Screen *s; { return (MaxCmapsOfScreen(s)); } + +Bool XDoesSaveUnders(s) Screen *s; { return (DoesSaveUnders(s)); } + +int XDoesBackingStore(s) Screen *s; { return (DoesBackingStore(s)); } + +long XEventMaskOfScreen(s) Screen *s; { return (EventMaskOfScreen(s)); } + +int XScreenNumberOfScreen (scr) + register Screen *scr; +{ + register Display *dpy = scr->display; + register Screen *dpyscr = dpy->screens; + register int i; + + for (i = 0; i < dpy->nscreens; i++, dpyscr++) { + if (scr == dpyscr) return i; + } + return -1; +} + +/* + * These macros are used to give some sugar to the image routines so that + * naive people are more comfortable with them. + */ +#undef XDestroyImage +XDestroyImage(ximage) + XImage *ximage; +{ + return((*((ximage)->f.destroy_image))((ximage))); +} +#undef XGetPixel +unsigned long XGetPixel(ximage, x, y) + XImage *ximage; + int x, y; +{ + return ((*((ximage)->f.get_pixel))((ximage), (x), (y))); +} +#undef XPutPixel +int XPutPixel(ximage, x, y, pixel) + XImage *ximage; + int x, y; + unsigned long pixel; +{ + return((*((ximage)->f.put_pixel))((ximage), (x), (y), (pixel))); +} +#undef XSubImage +XImage *XSubImage(ximage, x, y, width, height) + XImage *ximage; + int x, y; + unsigned int width, height; +{ + return((*((ximage)->f.sub_image))((ximage), (x), + (y), (width), (height))); +} +#undef XAddPixel +int XAddPixel(ximage, value) + XImage *ximage; + long value; +{ + return((*((ximage)->f.add_pixel))((ximage), (value))); +} + + +XNoOp (dpy) + register Display *dpy; +{ + register xReq *req; + + LockDisplay(dpy); + GetEmptyReq(NoOperation, req); + + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} diff --git a/src/MapRaised.c b/src/MapRaised.c new file mode 100644 index 00000000..e00cb75a --- /dev/null +++ b/src/MapRaised.c @@ -0,0 +1,48 @@ +/* $Xorg: MapRaised.c,v 1.4 2001/02/09 02:03:34 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XMapRaised (dpy, w) + Window w; + register Display *dpy; +{ + register xConfigureWindowReq *req; + register xResourceReq *req2; + unsigned long val = Above; /* needed for macro */ + + LockDisplay(dpy); + GetReqExtra(ConfigureWindow, 4, req); + req->window = w; + req->mask = CWStackMode; + OneDataCard32 (dpy, NEXTPTR(req,xConfigureWindowReq), val); + GetResReq (MapWindow, w, req2); + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} + diff --git a/src/MapSubs.c b/src/MapSubs.c new file mode 100644 index 00000000..39589e93 --- /dev/null +++ b/src/MapSubs.c @@ -0,0 +1,40 @@ +/* $Xorg: MapSubs.c,v 1.4 2001/02/09 02:03:34 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XMapSubwindows(dpy, win) + register Display *dpy; + Window win; +{ + register xResourceReq *req; + LockDisplay(dpy); + GetResReq(MapSubwindows, win, req); + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} diff --git a/src/MapWindow.c b/src/MapWindow.c new file mode 100644 index 00000000..e0c06efe --- /dev/null +++ b/src/MapWindow.c @@ -0,0 +1,41 @@ +/* $Xorg: MapWindow.c,v 1.4 2001/02/09 02:03:34 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XMapWindow (dpy, w) + Window w; + register Display *dpy; +{ + register xResourceReq *req; + LockDisplay (dpy); + GetResReq(MapWindow, w, req); + UnlockDisplay (dpy); + SyncHandle(); + return 1; +} + diff --git a/src/MaskEvent.c b/src/MaskEvent.c new file mode 100644 index 00000000..c51d7b9d --- /dev/null +++ b/src/MaskEvent.c @@ -0,0 +1,80 @@ +/* $Xorg: MaskEvent.c,v 1.4 2001/02/09 02:03:34 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#define NEED_EVENTS +#include "Xlibint.h" + +#ifdef __STDC__ +#define Const const +#else +#define Const /**/ +#endif + +extern long Const _Xevent_to_mask[]; +#define AllPointers (PointerMotionMask|PointerMotionHintMask|ButtonMotionMask) +#define AllButtons (Button1MotionMask|Button2MotionMask|Button3MotionMask|\ + Button4MotionMask|Button5MotionMask) + +/* + * return the next event in the queue matching one of the events in the mask. + * If no event, flush output, and wait until match succeeds. + * Events earlier in the queue are not discarded. + */ + +XMaskEvent (dpy, mask, event) + register Display *dpy; + long mask; /* Selected event mask. */ + register XEvent *event; /* XEvent to be filled in. */ +{ + register _XQEvent *prev, *qelt; + unsigned long qe_serial; + + LockDisplay(dpy); + prev = NULL; + while (1) { + for (qelt = prev ? prev->next : dpy->head; + qelt; + prev = qelt, qelt = qelt->next) { + if ((qelt->event.type < LASTEvent) && + (_Xevent_to_mask[qelt->event.type] & mask) && + ((qelt->event.type != MotionNotify) || + (mask & AllPointers) || + (mask & AllButtons & qelt->event.xmotion.state))) { + *event = qelt->event; + _XDeq(dpy, prev, qelt); + UnlockDisplay(dpy); + return 0; + } + } + if (prev) + qe_serial = prev->qserial_num; + _XReadEvents(dpy); + if (prev && prev->qserial_num != qe_serial) + /* another thread has snatched this event */ + prev = NULL; + } +} diff --git a/src/Misc.c b/src/Misc.c new file mode 100644 index 00000000..3b0b17d8 --- /dev/null +++ b/src/Misc.c @@ -0,0 +1,67 @@ +/* $Xorg: Misc.c,v 1.4 2001/02/09 02:03:34 xorgcvs Exp $ */ +/* + +Copyright 1988, 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. + +*/ + +#include "Xlibint.h" + +long XMaxRequestSize(dpy) + Display *dpy; +{ + return dpy->max_request_size; +} + +char *XResourceManagerString(dpy) + Display *dpy; +{ + return dpy->xdefaults; +} + +unsigned long XDisplayMotionBufferSize(dpy) + Display *dpy; +{ + return dpy->motion_buffer; +} + +XDisplayKeycodes(dpy, min_keycode_return, max_keycode_return) + Display *dpy; + int *min_keycode_return, *max_keycode_return; +{ + *min_keycode_return = dpy->min_keycode; + *max_keycode_return = dpy->max_keycode; + return 1; +} + +VisualID XVisualIDFromVisual(visual) + Visual *visual; +{ + return visual->visualid; +} + +long XExtendedMaxRequestSize(dpy) + Display *dpy; +{ + return dpy->bigreq_size; +} diff --git a/src/ModMap.c b/src/ModMap.c new file mode 100644 index 00000000..51a32101 --- /dev/null +++ b/src/ModMap.c @@ -0,0 +1,198 @@ +/* $Xorg: ModMap.c,v 1.4 2001/02/09 02:03:34 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#define NEED_REPLIES +#include "Xlibint.h" + +XModifierKeymap * +XGetModifierMapping(dpy) + register Display *dpy; +{ + xGetModifierMappingReply rep; + register xReq *req; + unsigned long nbytes; + XModifierKeymap *res; + + LockDisplay(dpy); + GetEmptyReq(GetModifierMapping, req); + (void) _XReply (dpy, (xReply *)&rep, 0, xFalse); + + nbytes = (unsigned long)rep.length << 2; + res = (XModifierKeymap *) Xmalloc(sizeof (XModifierKeymap)); + if (res) res->modifiermap = (KeyCode *) Xmalloc ((unsigned) nbytes); + if ((! res) || (! res->modifiermap)) { + if (res) Xfree((char *) res); + res = (XModifierKeymap *) NULL; + _XEatData(dpy, nbytes); + } else { + _XReadPad(dpy, (char *) res->modifiermap, (long) nbytes); + res->max_keypermod = rep.numKeyPerModifier; + } + + UnlockDisplay(dpy); + SyncHandle(); + return (res); +} + +/* + * Returns: + * 0 Success + * 1 Busy - one or more old or new modifiers are down + * 2 Failed - one or more new modifiers unacceptable + */ +int +XSetModifierMapping(dpy, modifier_map) + register Display *dpy; + register XModifierKeymap *modifier_map; +{ + register xSetModifierMappingReq *req; + xSetModifierMappingReply rep; + int mapSize = modifier_map->max_keypermod << 3; /* 8 modifiers */ + + LockDisplay(dpy); + GetReqExtra(SetModifierMapping, mapSize, req); + + req->numKeyPerModifier = modifier_map->max_keypermod; + + memcpy((char *) NEXTPTR(req,xSetModifierMappingReq), + (char *) modifier_map->modifiermap, + mapSize); + + (void) _XReply(dpy, (xReply *) & rep, + (SIZEOF(xSetModifierMappingReply) - SIZEOF(xReply)) >> 2, xTrue); + UnlockDisplay(dpy); + SyncHandle(); + return (rep.success); +} + +XModifierKeymap * +XNewModifiermap(keyspermodifier) + int keyspermodifier; +{ + XModifierKeymap *res = (XModifierKeymap *) Xmalloc((sizeof (XModifierKeymap))); + if (res) { + res->max_keypermod = keyspermodifier; + res->modifiermap = (keyspermodifier > 0 ? + (KeyCode *) Xmalloc((unsigned) (8 * keyspermodifier)) + : (KeyCode *) NULL); + if (keyspermodifier && (res->modifiermap == NULL)) { + Xfree((char *) res); + return (XModifierKeymap *) NULL; + } + } + return (res); +} + + +XFreeModifiermap(map) + XModifierKeymap *map; +{ + if (map) { + if (map->modifiermap) + Xfree((char *) map->modifiermap); + Xfree((char *) map); + } + return 1; +} + +#if NeedFunctionPrototypes +XModifierKeymap * +XInsertModifiermapEntry(XModifierKeymap *map, +#if NeedWidePrototypes + unsigned int keycode, +#else + KeyCode keycode, +#endif + int modifier) +#else +XModifierKeymap * +XInsertModifiermapEntry(map, keycode, modifier) + XModifierKeymap *map; + KeyCode keycode; + int modifier; +#endif +{ + XModifierKeymap *newmap; + int i, + row = modifier * map->max_keypermod, + newrow, + lastrow; + + for (i=0; i<map->max_keypermod; i++) { + if (map->modifiermap[ row+i ] == keycode) + return(map); /* already in the map */ + if (map->modifiermap[ row+i ] == 0) { + map->modifiermap[ row+i ] = keycode; + return(map); /* we added it without stretching the map */ + } + } + + /* stretch the map */ + if ((newmap = XNewModifiermap(map->max_keypermod+1)) == NULL) + return (XModifierKeymap *) NULL; + newrow = row = 0; + lastrow = newmap->max_keypermod * 8; + while (newrow < lastrow) { + for (i=0; i<map->max_keypermod; i++) + newmap->modifiermap[ newrow+i ] = map->modifiermap[ row+i ]; + newmap->modifiermap[ newrow+i ] = 0; + row += map->max_keypermod; + newrow += newmap->max_keypermod; + } + (void) XFreeModifiermap(map); + newrow = newmap->max_keypermod * modifier + newmap->max_keypermod - 1; + newmap->modifiermap[ newrow ] = keycode; + return(newmap); +} + +#if NeedFunctionPrototypes +XModifierKeymap * +XDeleteModifiermapEntry(XModifierKeymap *map, +#if NeedWidePrototypes + unsigned int keycode, +#else + KeyCode keycode, +#endif + int modifier) +#else +XModifierKeymap * +XDeleteModifiermapEntry(map, keycode, modifier) + XModifierKeymap *map; + KeyCode keycode; + int modifier; +#endif +{ + int i, + row = modifier * map->max_keypermod; + + for (i=0; i<map->max_keypermod; i++) { + if (map->modifiermap[ row+i ] == keycode) + map->modifiermap[ row+i ] = 0; + } + /* should we shrink the map?? */ + return (map); +} diff --git a/src/MoveWin.c b/src/MoveWin.c new file mode 100644 index 00000000..0ec2c8a8 --- /dev/null +++ b/src/MoveWin.c @@ -0,0 +1,61 @@ +/* $Xorg: MoveWin.c,v 1.4 2001/02/09 02:03:34 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XMoveWindow (dpy, w, x, y) + register Display *dpy; + Window w; + int x, y; +{ + register xConfigureWindowReq *req; + + LockDisplay(dpy); + GetReqExtra(ConfigureWindow, 8, req); + + req->window = w; + req->mask = CWX | CWY; + +#ifdef MUSTCOPY + { + long lx = (long) x, ly = (long) y; + dpy->bufptr -= 8; + Data32 (dpy, (long *) &lx, 4); /* order dictated by CWX and CWY */ + Data32 (dpy, (long *) &ly, 4); + } +#else + { + CARD32 *valuePtr = (CARD32 *) NEXTPTR(req,xConfigureWindowReq); + *valuePtr++ = x; + *valuePtr = y; + } +#endif /* MUSTCOPY */ + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} + diff --git a/src/NextEvent.c b/src/NextEvent.c new file mode 100644 index 00000000..40e7528a --- /dev/null +++ b/src/NextEvent.c @@ -0,0 +1,52 @@ +/* $Xorg: NextEvent.c,v 1.4 2001/02/09 02:03:34 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#define NEED_EVENTS +#include "Xlibint.h" + +/* + * Return next event in queue, or if none, flush output and wait for + * events. + */ + +XNextEvent (dpy, event) + register Display *dpy; + register XEvent *event; +{ + register _XQEvent *qelt; + + LockDisplay(dpy); + + if (dpy->head == NULL) + _XReadEvents(dpy); + qelt = dpy->head; + *event = qelt->event; + _XDeq(dpy, NULL, qelt); + UnlockDisplay(dpy); + return 0; +} + diff --git a/src/OCWrap.c b/src/OCWrap.c new file mode 100644 index 00000000..97a3aee0 --- /dev/null +++ b/src/OCWrap.c @@ -0,0 +1,161 @@ +/* $Xorg: OCWrap.c,v 1.4 2000/08/17 19:44:47 cpqbld Exp $ */ +/* + * Copyright 1992, 1993 by TOSHIBA Corp. + * + * 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 TOSHIBA not be used in advertising + * or publicity pertaining to distribution of the software without specific, + * written prior permission. TOSHIBA make no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * TOSHIBA DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING + * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL + * TOSHIBA 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. + * + * Author: Katsuhisa Yano TOSHIBA Corp. + * mopi@osa.ilab.toshiba.co.jp + */ + +#include "Xlibint.h" +#include "Xlcint.h" + +#if NeedVarargsPrototypes +XOC +XCreateOC(XOM om, ...) +#else +XOC +XCreateOC(om, va_alist) + XOM om; + va_dcl +#endif +{ + va_list var; + XlcArgList args; + XOC oc; + int num_args; + + Va_start(var, om); + _XlcCountVaList(var, &num_args); + va_end(var); + + Va_start(var, om); + _XlcVaToArgList(var, num_args, &args); + va_end(var); + + if (args == (XlcArgList) NULL) + return (XOC) NULL; + + oc = (*om->methods->create_oc)(om, args, num_args); + + Xfree(args); + + if (oc) { + oc->core.next = om->core.oc_list; + om->core.oc_list = oc; + } + + return oc; +} + +void +XDestroyOC(oc) + XOC oc; +{ + XOC prev, oc_list; + + prev = oc_list = oc->core.om->core.oc_list; + if (oc_list == oc) + oc->core.om->core.oc_list = oc_list->core.next; + else { + while ((oc_list = oc_list->core.next)) { + if (oc_list == oc) { + prev->core.next = oc_list->core.next; + break; + } + prev = oc_list; + } + } + + (*oc->methods->destroy)(oc); +} + +XOM +XOMOfOC(oc) + XOC oc; +{ + return oc->core.om; +} + +#if NeedVarargsPrototypes +char * +XSetOCValues(XOC oc, ...) +#else +char * +XSetOCValues(oc, va_alist) + XOC oc; + va_dcl +#endif +{ + va_list var; + XlcArgList args; + char *ret; + int num_args; + + Va_start(var, oc); + _XlcCountVaList(var, &num_args); + va_end(var); + + Va_start(var, oc); + _XlcVaToArgList(var, num_args, &args); + va_end(var); + + if (args == (XlcArgList) NULL) + return (char *) NULL; + + ret = (*oc->methods->set_values)(oc, args, num_args); + + Xfree(args); + + return ret; +} + +#if NeedVarargsPrototypes +char * +XGetOCValues(XOC oc, ...) +#else +char * +XGetOCValues(oc, va_alist) + XOC oc; + va_dcl +#endif +{ + va_list var; + XlcArgList args; + char *ret; + int num_args; + + Va_start(var, oc); + _XlcCountVaList(var, &num_args); + va_end(var); + + Va_start(var, oc); + _XlcVaToArgList(var, num_args, &args); + va_end(var); + + if (args == (XlcArgList) NULL) + return (char *) NULL; + + ret = (*oc->methods->get_values)(oc, args, num_args); + + Xfree(args); + + return ret; +} diff --git a/src/OMWrap.c b/src/OMWrap.c new file mode 100644 index 00000000..d97bd647 --- /dev/null +++ b/src/OMWrap.c @@ -0,0 +1,152 @@ +/* $Xorg: OMWrap.c,v 1.4 2000/08/17 19:44:47 cpqbld Exp $ */ +/* + * Copyright 1992, 1993 by TOSHIBA Corp. + * + * 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 TOSHIBA not be used in advertising + * or publicity pertaining to distribution of the software without specific, + * written prior permission. TOSHIBA make no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * TOSHIBA DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING + * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL + * TOSHIBA 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. + * + * Author: Katsuhisa Yano TOSHIBA Corp. + * mopi@osa.ilab.toshiba.co.jp + */ + +#include "Xlibint.h" +#include "Xlcint.h" + +XOM +#if NeedFunctionPrototypes +XOpenOM(Display *dpy, XrmDatabase rdb, _Xconst char *res_name, + _Xconst char *res_class) +#else +XOpenOM(dpy, rdb, res_name, res_class) + Display *dpy; + XrmDatabase rdb; + char *res_name; + char *res_class; +#endif +{ + XLCd lcd = _XOpenLC((char *) NULL); + + if (lcd == NULL) + return (XOM) NULL; + + if (lcd->methods->open_om) + return (*lcd->methods->open_om)(lcd, dpy, rdb, res_name, res_class); + + return (XOM) NULL; +} + +Status +XCloseOM(om) + XOM om; +{ + XOC oc, next; + XLCd lcd = om->core.lcd; + + next = om->core.oc_list; + + while ((oc = next)) { + next = oc->core.next; + (*oc->methods->destroy)(oc); + } + + om->core.oc_list = NULL; + + _XCloseLC(lcd); + + return (*om->methods->close)(om); +} + +#if NeedVarargsPrototypes +char * +XSetOMValues(XOM om, ...) +#else +char * +XSetOMValues(om, va_alist) + XOM om; + va_dcl +#endif +{ + va_list var; + XlcArgList args; + char *ret; + int num_args; + + Va_start(var, om); + _XlcCountVaList(var, &num_args); + va_end(var); + + Va_start(var, om); + _XlcVaToArgList(var, num_args, &args); + va_end(var); + + if (args == (XlcArgList) NULL) + return (char *) NULL; + + ret = (*om->methods->set_values)(om, args, num_args); + + Xfree(args); + + return ret; +} + +#if NeedVarargsPrototypes +char * +XGetOMValues(XOM om, ...) +#else +char * +XGetOMValues(om, va_alist) + XOM om; + va_dcl +#endif +{ + va_list var; + XlcArgList args; + char *ret; + int num_args; + + Va_start(var, om); + _XlcCountVaList(var, &num_args); + va_end(var); + + Va_start(var, om); + _XlcVaToArgList(var, num_args, &args); + va_end(var); + + if (args == (XlcArgList) NULL) + return (char *) NULL; + + ret = (*om->methods->get_values)(om, args, num_args); + + Xfree(args); + + return ret; +} + +Display * +XDisplayOfOM(om) + XOM om; +{ + return om->core.display; +} + +char * +XLocaleOfOM(om) + XOM om; +{ + return om->core.lcd->core->name; +} diff --git a/src/OpenDis.c b/src/OpenDis.c new file mode 100644 index 00000000..6207fdd2 --- /dev/null +++ b/src/OpenDis.c @@ -0,0 +1,760 @@ +/* $Xorg: OpenDis.c,v 1.4 2001/02/09 02:03:34 xorgcvs Exp $ */ +/* + +Copyright 1985, 1986, 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. + +*/ + +#define NEED_REPLIES +#define NEED_EVENTS +#include "Xlibint.h" +#include <X11/Xtrans.h> +#include <X11/Xatom.h> +#include "bigreqstr.h" +#include <stdio.h> + +#ifdef X_NOT_STDC_ENV +extern char *getenv(); +#endif + +#ifdef X_NOT_POSIX +#define Size_t unsigned int +#else +#define Size_t size_t +#endif + +#define bignamelen (sizeof(XBigReqExtensionName) - 1) + +typedef struct { + unsigned long seq; + int opcode; +} _XBigReqState; + +extern int _Xdebug; +#ifdef WIN32 +int *_Xdebug_p = &_Xdebug; +#endif + +#ifdef XTHREADS +int (*_XInitDisplayLock_fn)() = NULL; +void (*_XFreeDisplayLock_fn)() = NULL; + +#define InitDisplayLock(d) (_XInitDisplayLock_fn ? (*_XInitDisplayLock_fn)(d) : Success) +#define FreeDisplayLock(d) if (_XFreeDisplayLock_fn) (*_XFreeDisplayLock_fn)(d) +#else +#define InitDisplayLock(dis) Success +#define FreeDisplayLock(dis) +#endif + +static xReq _dummy_request = { + 0, 0, 0 +}; + +static void OutOfMemory(); +static Bool _XBigReqHandler(); + +extern Bool _XWireToEvent(); +extern Status _XUnknownNativeEvent(); +extern Bool _XUnknownWireEvent(); +/* + * Connects to a server, creates a Display object and returns a pointer to + * the newly created Display back to the caller. + */ +#if NeedFunctionPrototypes +Display *XOpenDisplay ( + register _Xconst char *display) +#else +Display *XOpenDisplay (display) + register char *display; +#endif +{ + register Display *dpy; /* New Display object being created. */ + register int i; + int j, k; /* random iterator indexes */ + char *display_name; /* pointer to display name */ + int endian; /* to determine which endian. */ + xConnClientPrefix client; /* client information */ + xConnSetupPrefix prefix; /* prefix information */ + int vendorlen; /* length of vendor string */ + char *setup = NULL; /* memory allocated at startup */ + char *fullname = NULL; /* expanded name of display */ + int idisplay; /* display number */ + int iscreen; /* screen number */ + int prefixread = 0; /* setup prefix already read? */ + union { + xConnSetup *setup; + char *failure; + char *vendor; + xPixmapFormat *sf; + xWindowRoot *rp; + xDepth *dp; + xVisualType *vp; + } u; /* proto data returned from server */ + long setuplength; /* number of bytes in setup message */ + char *conn_auth_name, *conn_auth_data; + int conn_auth_namelen, conn_auth_datalen; + unsigned long mask; + extern Bool _XSendClientPrefix(); + extern XtransConnInfo _X11TransConnectDisplay(); + extern XID _XAllocID(); + extern void _XAllocIDs(); + + /* + * If the display specifier string supplied as an argument to this + * routine is NULL or a pointer to NULL, read the DISPLAY variable. + */ + if (display == NULL || *display == '\0') { + if ((display_name = getenv("DISPLAY")) == NULL) { + /* Oops! No DISPLAY environment variable - error. */ + return(NULL); + } + } + else { + /* Display is non-NULL, copy the pointer */ + display_name = (char *)display; + } +/* + * Set the default error handlers. This allows the global variables to + * default to NULL for use with shared libraries. + */ + if (_XErrorFunction == NULL) (void) XSetErrorHandler (NULL); + if (_XIOErrorFunction == NULL) (void) XSetIOErrorHandler (NULL); + +/* + * Attempt to allocate a display structure. Return NULL if allocation fails. + */ + if ((dpy = (Display *)Xcalloc(1, sizeof(Display))) == NULL) { + return(NULL); + } + +/* + * Call the Connect routine to get the transport connection object. + * If NULL is returned, the connection failed. The connect routine + * will set fullname to point to the expanded name. + */ + + if ((dpy->trans_conn = _X11TransConnectDisplay ( + display_name, &fullname, &idisplay, + &iscreen, &conn_auth_name, + &conn_auth_namelen, &conn_auth_data, + &conn_auth_datalen)) == NULL) { + Xfree ((char *) dpy); + return(NULL); + } + + dpy->fd = _X11TransGetConnectionNumber (dpy->trans_conn); + + /* Initialize as much of the display structure as we can. + * Initialize pointers to NULL so that XFreeDisplayStructure will + * work if we run out of memory before we finish initializing. + */ + dpy->display_name = fullname; + dpy->keysyms = (KeySym *) NULL; + dpy->modifiermap = NULL; + dpy->lock_meaning = NoSymbol; + dpy->keysyms_per_keycode = 0; + dpy->xdefaults = (char *)NULL; + dpy->scratch_length = 0L; + dpy->scratch_buffer = NULL; + dpy->key_bindings = NULL; + dpy->ext_procs = (_XExtension *)NULL; + dpy->ext_data = (XExtData *)NULL; + dpy->ext_number = 0; + dpy->event_vec[X_Error] = _XUnknownWireEvent; + dpy->event_vec[X_Reply] = _XUnknownWireEvent; + dpy->wire_vec[X_Error] = _XUnknownNativeEvent; + dpy->wire_vec[X_Reply] = _XUnknownNativeEvent; + for (i = KeyPress; i < LASTEvent; i++) { + dpy->event_vec[i] = _XWireToEvent; + dpy->wire_vec[i] = NULL; + } + for (i = LASTEvent; i < 128; i++) { + dpy->event_vec[i] = _XUnknownWireEvent; + dpy->wire_vec[i] = _XUnknownNativeEvent; + } + dpy->resource_id = 0; + dpy->db = (struct _XrmHashBucketRec *)NULL; + dpy->cursor_font = None; + dpy->flags = 0; + dpy->async_handlers = NULL; + dpy->screens = NULL; + dpy->vendor = NULL; + dpy->buffer = NULL; + dpy->atoms = NULL; + dpy->error_vec = NULL; + dpy->context_db = NULL; + dpy->free_funcs = NULL; + dpy->pixmap_format = NULL; + dpy->cms.clientCmaps = NULL; + dpy->cms.defaultCCCs = NULL; + dpy->cms.perVisualIntensityMaps = NULL; + dpy->im_filters = NULL; + dpy->bigreq_size = 0; + dpy->lock = NULL; + dpy->lock_fns = NULL; + dpy->qfree = NULL; + dpy->next_event_serial_num = 1; + dpy->im_fd_info = NULL; + dpy->im_fd_length = 0; + dpy->conn_watchers = NULL; + dpy->watcher_count = 0; + dpy->filedes = NULL; + dpy->flushes = NULL; + dpy->xcmisc_opcode = 0; + dpy->xkb_info = NULL; + +/* + * Setup other information in this display structure. + */ + dpy->vnumber = X_PROTOCOL; + dpy->resource_alloc = _XAllocID; + dpy->idlist_alloc = _XAllocIDs; + dpy->synchandler = NULL; + dpy->savedsynchandler = NULL; + dpy->request = 0; + dpy->last_request_read = 0; + dpy->default_screen = iscreen; /* Value returned by ConnectDisplay */ + dpy->last_req = (char *)&_dummy_request; + + /* Initialize the display lock */ + if (InitDisplayLock(dpy) != 0) { + OutOfMemory (dpy, setup); + return(NULL); + } + + if (!_XPollfdCacheInit(dpy)) { + OutOfMemory (dpy, setup); + return(NULL); + } + + /* Set up the output buffers. */ + if ((dpy->bufptr = dpy->buffer = Xmalloc(BUFSIZE)) == NULL) { + OutOfMemory (dpy, setup); + return(NULL); + } + dpy->bufmax = dpy->buffer + BUFSIZE; + + /* Set up the input event queue and input event queue parameters. */ + dpy->head = dpy->tail = NULL; + dpy->qlen = 0; + + /* Set up free-function record */ + if ((dpy->free_funcs = (_XFreeFuncRec *)Xcalloc(1, + sizeof(_XFreeFuncRec))) + == NULL) { + OutOfMemory (dpy, setup); + return(NULL); + } + +/* + * The xConnClientPrefix describes the initial connection setup information + * and is followed by the authorization information. Sites that are interested + * in security are strongly encouraged to use an authentication and + * authorization system such as Kerberos. + */ + endian = 1; + if (*(char *) &endian) + client.byteOrder = '\154'; /* 'l' */ + else + client.byteOrder = '\102'; /* 'B' */ + client.majorVersion = X_PROTOCOL; + client.minorVersion = X_PROTOCOL_REVISION; + client.nbytesAuthProto = conn_auth_namelen; + client.nbytesAuthString = conn_auth_datalen; + prefixread = _XSendClientPrefix(dpy, &client, + conn_auth_name, conn_auth_data, + &prefix); + if (prefixread < 0) + { + _XDisconnectDisplay (dpy->trans_conn); + Xfree ((char *)dpy); + return(NULL); + } + if (conn_auth_name) Xfree(conn_auth_name); + if (conn_auth_data) Xfree(conn_auth_data); +/* + * Now see if connection was accepted... + */ + /* these internal functions expect the display to be locked */ + LockDisplay(dpy); + + if (prefixread == 0) + _XRead (dpy, (char *)&prefix,(long)SIZEOF(xConnSetupPrefix)); + + /* an Authenticate reply we weren't expecting? */ + if (prefix.success != xTrue && prefix.success != xFalse) { + fprintf (stderr, + "Xlib: unexpected connection setup reply from server, type %d.\r\n", + prefix.success); + _XDisconnectDisplay (dpy->trans_conn); + Xfree ((char *)dpy); + return(NULL); + } + + if (prefix.majorVersion != X_PROTOCOL) { + /* XXX - printing messages marks a bad programming interface */ + fprintf (stderr, + "Xlib: client uses different protocol version (%d) than server (%d)!\r\n", + X_PROTOCOL, prefix.majorVersion); + _XDisconnectDisplay (dpy->trans_conn); + Xfree ((char *)dpy); + return(NULL); + } + + setuplength = prefix.length << 2; + if ( (u.setup = (xConnSetup *) + (setup = Xmalloc ((unsigned) setuplength))) == NULL) { + _XDisconnectDisplay (dpy->trans_conn); + Xfree ((char *)dpy); + return(NULL); + } + _XRead (dpy, (char *)u.setup, setuplength); +/* + * If the connection was not accepted by the server due to problems, + * give error message to the user.... + */ + if (prefix.success != xTrue) { + /* XXX - printing messages marks a bad programming interface */ + fprintf (stderr, + "Xlib: connection to \"%s\" refused by server\r\nXlib: ", + fullname); + (void) fwrite (u.failure, (Size_t)sizeof(char), + (Size_t)prefix.lengthReason, stderr); + (void) fwrite ("\r\n", sizeof(char), 2, stderr); + OutOfMemory(dpy, setup); + return (NULL); + } + +/* + * We succeeded at authorization, so let us move the data into + * the display structure. + */ + dpy->proto_major_version= prefix.majorVersion; + dpy->proto_minor_version= prefix.minorVersion; + dpy->release = u.setup->release; + dpy->resource_base = u.setup->ridBase; + dpy->resource_mask = u.setup->ridMask; + dpy->min_keycode = u.setup->minKeyCode; + dpy->max_keycode = u.setup->maxKeyCode; + dpy->motion_buffer = u.setup->motionBufferSize; + dpy->nformats = u.setup->numFormats; + dpy->nscreens = u.setup->numRoots; + dpy->byte_order = u.setup->imageByteOrder; + dpy->bitmap_unit = u.setup->bitmapScanlineUnit; + dpy->bitmap_pad = u.setup->bitmapScanlinePad; + dpy->bitmap_bit_order = u.setup->bitmapBitOrder; + dpy->max_request_size = u.setup->maxRequestSize; + mask = dpy->resource_mask; + dpy->resource_shift = 0; + while (!(mask & 1)) { + dpy->resource_shift++; + mask = mask >> 1; + } + dpy->resource_max = (dpy->resource_mask >> dpy->resource_shift) - 5; +/* + * now extract the vendor string... String must be null terminated, + * padded to multiple of 4 bytes. + */ + dpy->vendor = (char *) Xmalloc((unsigned) (u.setup->nbytesVendor + 1)); + if (dpy->vendor == NULL) { + OutOfMemory(dpy, setup); + return (NULL); + } + vendorlen = u.setup->nbytesVendor; + u.setup = (xConnSetup *) (((char *) u.setup) + sz_xConnSetup); + (void) strncpy(dpy->vendor, u.vendor, vendorlen); + dpy->vendor[vendorlen] = '\0'; + vendorlen = (vendorlen + 3) & ~3; /* round up */ + memmove (setup, u.vendor + vendorlen, + (int) setuplength - sz_xConnSetup - vendorlen); + u.vendor = setup; +/* + * Now iterate down setup information..... + */ + dpy->pixmap_format = + (ScreenFormat *)Xmalloc( + (unsigned) (dpy->nformats *sizeof(ScreenFormat))); + if (dpy->pixmap_format == NULL) { + OutOfMemory (dpy, setup); + return(NULL); + } +/* + * First decode the Z axis Screen format information. + */ + for (i = 0; i < dpy->nformats; i++) { + register ScreenFormat *fmt = &dpy->pixmap_format[i]; + fmt->depth = u.sf->depth; + fmt->bits_per_pixel = u.sf->bitsPerPixel; + fmt->scanline_pad = u.sf->scanLinePad; + fmt->ext_data = NULL; + u.sf = (xPixmapFormat *) (((char *) u.sf) + sz_xPixmapFormat); + } + +/* + * next the Screen structures. + */ + dpy->screens = + (Screen *)Xmalloc((unsigned) dpy->nscreens*sizeof(Screen)); + if (dpy->screens == NULL) { + OutOfMemory (dpy, setup); + return(NULL); + } +/* + * Now go deal with each screen structure. + */ + for (i = 0; i < dpy->nscreens; i++) { + register Screen *sp = &dpy->screens[i]; + VisualID root_visualID = u.rp->rootVisualID; + sp->display = dpy; + sp->root = u.rp->windowId; + sp->cmap = u.rp->defaultColormap; + sp->white_pixel = u.rp->whitePixel; + sp->black_pixel = u.rp->blackPixel; + sp->root_input_mask = u.rp->currentInputMask; + sp->width = u.rp->pixWidth; + sp->height = u.rp->pixHeight; + sp->mwidth = u.rp->mmWidth; + sp->mheight = u.rp->mmHeight; + sp->min_maps = u.rp->minInstalledMaps; + sp->max_maps = u.rp->maxInstalledMaps; + sp->backing_store= u.rp->backingStore; + sp->save_unders = u.rp->saveUnders; + sp->root_depth = u.rp->rootDepth; + sp->ndepths = u.rp->nDepths; + sp->ext_data = NULL; + u.rp = (xWindowRoot *) (((char *) u.rp) + sz_xWindowRoot); +/* + * lets set up the depth structures. + */ + sp->depths = (Depth *)Xmalloc( + (unsigned)sp->ndepths*sizeof(Depth)); + if (sp->depths == NULL) { + OutOfMemory (dpy, setup); + return(NULL); + } + /* + * for all depths on this screen. + */ + for (j = 0; j < sp->ndepths; j++) { + Depth *dp = &sp->depths[j]; + dp->depth = u.dp->depth; + dp->nvisuals = u.dp->nVisuals; + u.dp = (xDepth *) (((char *) u.dp) + sz_xDepth); + if (dp->nvisuals > 0) { + dp->visuals = + (Visual *)Xmalloc((unsigned)dp->nvisuals*sizeof(Visual)); + if (dp->visuals == NULL) { + OutOfMemory (dpy, setup); + return(NULL); + } + for (k = 0; k < dp->nvisuals; k++) { + register Visual *vp = &dp->visuals[k]; + vp->visualid = u.vp->visualID; + vp->class = u.vp->class; + vp->bits_per_rgb= u.vp->bitsPerRGB; + vp->map_entries = u.vp->colormapEntries; + vp->red_mask = u.vp->redMask; + vp->green_mask = u.vp->greenMask; + vp->blue_mask = u.vp->blueMask; + vp->ext_data = NULL; + u.vp = (xVisualType *) (((char *) u.vp) + + sz_xVisualType); + } + } else { + dp->visuals = (Visual *) NULL; + } + } + sp->root_visual = _XVIDtoVisual(dpy, root_visualID); + } + + +/* + * Now start talking to the server to setup all other information... + */ + + Xfree (setup); /* all finished with setup information */ + +/* + * Make sure default screen is legal. + */ + if (iscreen >= dpy->nscreens) { + OutOfMemory(dpy, (char *) NULL); + return(NULL); + } + +/* + * finished calling internal routines, now unlock for external routines + */ + UnlockDisplay(dpy); + +/* + * Set up other stuff clients are always going to use. + */ + for (i = 0; i < dpy->nscreens; i++) { + register Screen *sp = &dpy->screens[i]; + XGCValues values; + values.foreground = sp->black_pixel; + values.background = sp->white_pixel; + if ((sp->default_gc = XCreateGC (dpy, sp->root, + GCForeground|GCBackground, + &values)) == NULL) { + OutOfMemory(dpy, (char *) NULL); + return (NULL); + } + } +/* + * call into synchronization routine so that all programs can be + * forced synchronous + */ + (void) XSynchronize(dpy, _Xdebug); + +/* + * get availability of large requests, and + * get the resource manager database off the root window. + */ + LockDisplay(dpy); + { + _XAsyncHandler async; + _XBigReqState async_state; + xQueryExtensionReq *qreq; + xGetPropertyReply reply; + xGetPropertyReq *req; + xBigReqEnableReq *breq; + xBigReqEnableReply brep; + + GetReq(QueryExtension, qreq); + async_state.seq = dpy->request; + async_state.opcode = 0; + async.next = dpy->async_handlers; + async.handler = _XBigReqHandler; + async.data = (XPointer)&async_state; + dpy->async_handlers = &async; + qreq->nbytes = bignamelen; + qreq->length += (bignamelen+3)>>2; + Data(dpy, XBigReqExtensionName, bignamelen); + + GetReq (GetProperty, req); + req->window = RootWindow(dpy, 0); + req->property = XA_RESOURCE_MANAGER; + req->type = XA_STRING; + req->delete = False; + req->longOffset = 0; + req->longLength = 100000000L; + + if (_XReply (dpy, (xReply *) &reply, 0, xFalse)) { + if (reply.format == 8 && reply.propertyType == XA_STRING && + (dpy->xdefaults = Xmalloc (reply.nItems + 1))) { + _XReadPad (dpy, dpy->xdefaults, reply.nItems); + dpy->xdefaults[reply.nItems] = '\0'; + } + else if (reply.propertyType != None) + _XEatData(dpy, reply.nItems * (reply.format >> 3)); + } + DeqAsyncHandler(dpy, &async); + if (async_state.opcode) { + GetReq(BigReqEnable, breq); + breq->reqType = async_state.opcode; + breq->brReqType = X_BigReqEnable; + if (_XReply(dpy, (xReply *)&brep, 0, xFalse)) + dpy->bigreq_size = brep.max_request_size; + } + } + UnlockDisplay(dpy); + +#ifdef MOTIFBC + { + extern Display *_XHeadOfDisplayList; + _XHeadOfDisplayList = dpy; + } +#endif +#ifdef XKB + XkbUseExtension(dpy,NULL,NULL); +#endif +/* + * and return successfully + */ + return(dpy); +} + +static Bool +_XBigReqHandler(dpy, rep, buf, len, data) + register Display *dpy; + register xReply *rep; + char *buf; + int len; + XPointer data; +{ + _XBigReqState *state; + xQueryExtensionReply replbuf; + xQueryExtensionReply *repl; + + state = (_XBigReqState *)data; + if (dpy->last_request_read != state->seq) + return False; + if (rep->generic.type == X_Error) + return True; + repl = (xQueryExtensionReply *) + _XGetAsyncReply(dpy, (char *)&replbuf, rep, buf, len, + (SIZEOF(xQueryExtensionReply) - SIZEOF(xReply)) >> 2, + True); + if (repl->present) + state->opcode = repl->major_opcode; + return True; +} + + +/* XFreeDisplayStructure frees all the storage associated with a + * Display. It is used by XOpenDisplay if it runs out of memory, + * and also by XCloseDisplay. It needs to check whether all pointers + * are non-NULL before dereferencing them, since it may be called + * by XOpenDisplay before the Display structure is fully formed. + * XOpenDisplay must be sure to initialize all the pointers to NULL + * before the first possible call on this. + */ + +void _XFreeDisplayStructure(dpy) + register Display *dpy; +{ + while (dpy->ext_procs) { + _XExtension *ext = dpy->ext_procs; + dpy->ext_procs = ext->next; + if (ext->name) + Xfree (ext->name); + Xfree ((char *)ext); + } + if (dpy->im_filters) + (*dpy->free_funcs->im_filters)(dpy); + if (dpy->cms.clientCmaps) + (*dpy->free_funcs->clientCmaps)(dpy); + if (dpy->cms.defaultCCCs) + (*dpy->free_funcs->defaultCCCs)(dpy); + if (dpy->cms.perVisualIntensityMaps) + (*dpy->free_funcs->intensityMaps)(dpy); + if (dpy->atoms) + (*dpy->free_funcs->atoms)(dpy); + if (dpy->modifiermap) + (*dpy->free_funcs->modifiermap)(dpy->modifiermap); + if (dpy->key_bindings) + (*dpy->free_funcs->key_bindings)(dpy); + if (dpy->context_db) + (*dpy->free_funcs->context_db)(dpy); + if (dpy->xkb_info) + (*dpy->free_funcs->xkb)(dpy); + + if (dpy->screens) { + register int i; + + for (i = 0; i < dpy->nscreens; i++) { + Screen *sp = &dpy->screens[i]; + + if (sp->depths) { + register int j; + + for (j = 0; j < sp->ndepths; j++) { + Depth *dp = &sp->depths[j]; + + if (dp->visuals) { + register int k; + + for (k = 0; k < dp->nvisuals; k++) + _XFreeExtData (dp->visuals[k].ext_data); + Xfree ((char *) dp->visuals); + } + } + + Xfree ((char *) sp->depths); + } + + _XFreeExtData (sp->ext_data); + } + + Xfree ((char *)dpy->screens); + } + + if (dpy->pixmap_format) { + register int i; + + for (i = 0; i < dpy->nformats; i++) + _XFreeExtData (dpy->pixmap_format[i].ext_data); + Xfree ((char *)dpy->pixmap_format); + } + + if (dpy->display_name) + Xfree (dpy->display_name); + if (dpy->vendor) + Xfree (dpy->vendor); + + if (dpy->buffer) + Xfree (dpy->buffer); + if (dpy->keysyms) + Xfree ((char *) dpy->keysyms); + if (dpy->xdefaults) + Xfree (dpy->xdefaults); + if (dpy->error_vec) + Xfree ((char *)dpy->error_vec); + + _XFreeExtData (dpy->ext_data); + if (dpy->free_funcs) + Xfree ((char *)dpy->free_funcs); + if (dpy->scratch_buffer) + Xfree (dpy->scratch_buffer); + FreeDisplayLock(dpy); + + if (dpy->qfree) { + register _XQEvent *qelt = dpy->qfree; + + while (qelt) { + register _XQEvent *qnxt = qelt->next; + Xfree ((char *) qelt); + qelt = qnxt; + } + } + while (dpy->im_fd_info) { + struct _XConnectionInfo *conni = dpy->im_fd_info; + dpy->im_fd_info = conni->next; + if (conni->watch_data) + Xfree (conni->watch_data); + Xfree (conni); + } + if (dpy->conn_watchers) { + struct _XConnWatchInfo *watcher = dpy->conn_watchers; + dpy->conn_watchers = watcher->next; + Xfree (watcher); + } + if (dpy->filedes) + Xfree (dpy->filedes); + + Xfree ((char *)dpy); +} + +/* OutOfMemory is called if malloc fails. XOpenDisplay returns NULL + after this returns. */ + +static void OutOfMemory (dpy, setup) + Display *dpy; + char *setup; +{ + _XDisconnectDisplay (dpy->trans_conn); + _XFreeDisplayStructure (dpy); + if (setup) Xfree (setup); +} diff --git a/src/ParseCmd.c b/src/ParseCmd.c new file mode 100644 index 00000000..e2e302d0 --- /dev/null +++ b/src/ParseCmd.c @@ -0,0 +1,234 @@ +/* $Xorg: ParseCmd.c,v 1.4 2001/02/09 02:03:35 xorgcvs Exp $ */ + +/*********************************************************** + +Copyright 1987, 1988, 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, 1988 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. + +******************************************************************/ + +/* XrmParseCommand() + + Parse command line and store argument values into resource database + + Allows any un-ambiguous abbreviation for an option name, but requires + that the table be ordered with any options that are prefixes of + other options appearing before the longer version in the table. +*/ + +#include "Xlibint.h" +#include <X11/Xresource.h> +#include <stdio.h> + + +static void _XReportParseError(arg, msg) + XrmOptionDescRec *arg; + char *msg; +{ + (void) fprintf(stderr, "Error parsing argument \"%s\" (%s); %s\n", + arg->option, arg->specifier, msg); + exit(1); +} + +#if NeedFunctionPrototypes +void XrmParseCommand( + XrmDatabase *pdb, /* data base */ + register XrmOptionDescList options, /* pointer to table of valid options */ + int num_options, /* number of options */ + _Xconst char *prefix, /* name to prefix resources with */ + int *argc, /* address of argument count */ + char **argv) /* argument list (command line) */ +#else +void XrmParseCommand(pdb, options, num_options, prefix, argc, argv) + XrmDatabase *pdb; /* data base */ + register XrmOptionDescList options; /* pointer to table of valid options */ + int num_options; /* number of options */ + char *prefix; /* name to prefix resources with */ + int *argc; /* address of argument count */ + char **argv; /* argument list (command line) */ +#endif +{ + int foundOption; + char **argsave; + register int i, myargc; + XrmBinding bindings[100]; + XrmQuark quarks[100]; + XrmBinding *start_bindings; + XrmQuark *start_quarks; + char *optP, *argP, optchar, argchar; + int matches; + enum {DontCare, Check, NotSorted, Sorted} table_is_sorted; + char **argend; + +#define PutCommandResource(value_str) \ + { \ + XrmStringToBindingQuarkList( \ + options[i].specifier, start_bindings, start_quarks); \ + XrmQPutStringResource(pdb, bindings, quarks, value_str); \ + } /* PutCommandResource */ + + myargc = (*argc); + argend = argv + myargc; + argsave = ++argv; + + /* Initialize bindings/quark list with prefix (typically app name). */ + quarks[0] = XrmStringToName(prefix); + bindings[0] = XrmBindTightly; + start_quarks = quarks+1; + start_bindings = bindings+1; + + table_is_sorted = (myargc > 2) ? Check : DontCare; + for (--myargc; myargc > 0; --myargc, ++argv) { + foundOption = False; + matches = 0; + for (i=0; i < num_options; ++i) { + /* checking the sort order first insures we don't have to + re-do the check if the arg hits on the last entry in + the table. Useful because usually '=' is the last entry + and users frequently specify geometry early in the command */ + if (table_is_sorted == Check && i > 0 && + strcmp(options[i].option, options[i-1].option) < 0) { + table_is_sorted = NotSorted; + } + for (argP = *argv, optP = options[i].option; + (optchar = *optP++) && + (argchar = *argP++) && + argchar == optchar;); + if (!optchar) { + if (!*argP || + options[i].argKind == XrmoptionStickyArg || + options[i].argKind == XrmoptionIsArg) { + /* give preference to exact matches, StickyArg and IsArg */ + matches = 1; + foundOption = i; + break; + } + } + else if (!argchar) { + /* may be an abbreviation for this option */ + matches++; + foundOption = i; + } + else if (table_is_sorted == Sorted && optchar > argchar) { + break; + } + if (table_is_sorted == Check && i > 0 && + strcmp(options[i].option, options[i-1].option) < 0) { + table_is_sorted = NotSorted; + } + } + if (table_is_sorted == Check && i >= (num_options-1)) + table_is_sorted = Sorted; + if (matches == 1) { + i = foundOption; + switch (options[i].argKind){ + case XrmoptionNoArg: + --(*argc); + PutCommandResource(options[i].value); + break; + + case XrmoptionIsArg: + --(*argc); + PutCommandResource(*argv); + break; + + case XrmoptionStickyArg: + --(*argc); + PutCommandResource(argP); + break; + + case XrmoptionSepArg: + if (myargc > 1) { + ++argv; --myargc; --(*argc); --(*argc); + PutCommandResource(*argv); + } else + (*argsave++) = (*argv); + break; + + case XrmoptionResArg: + if (myargc > 1) { + ++argv; --myargc; --(*argc); --(*argc); + XrmPutLineResource(pdb, *argv); + } else + (*argsave++) = (*argv); + break; + + case XrmoptionSkipArg: + if (myargc > 1) { + --myargc; + (*argsave++) = (*argv++); + } + (*argsave++) = (*argv); + break; + + case XrmoptionSkipLine: + for (; myargc > 0; myargc--) + (*argsave++) = (*argv++); + break; + + case XrmoptionSkipNArgs: + { + register int j = 1 + (int) options[i].value; + + if (j > myargc) j = myargc; + for (; j > 0; j--) { + (*argsave++) = (*argv++); + myargc--; + } + argv--; /* went one too far before */ + myargc++; + } + break; + + default: + _XReportParseError (&options[i], "unknown kind"); + break; + } + } + else + (*argsave++) = (*argv); /*compress arglist*/ + } + + if (argsave < argend) + (*argsave)=NULL; /* put NULL terminator on compressed argv */ +} diff --git a/src/ParseCol.c b/src/ParseCol.c new file mode 100644 index 00000000..1520384a --- /dev/null +++ b/src/ParseCol.c @@ -0,0 +1,135 @@ +/* $Xorg: ParseCol.c,v 1.4 2001/02/09 02:03:35 xorgcvs Exp $ */ +/* + +Copyright 1985, 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. + +*/ + +#define NEED_REPLIES +#include <stdio.h> +#include "Xlibint.h" +#include "Xcmsint.h" + +extern void _XcmsRGB_to_XColor(); + +#if NeedFunctionPrototypes +Status XParseColor ( + register Display *dpy, + Colormap cmap, + _Xconst char *spec, + XColor *def) +#else +Status XParseColor (dpy, cmap, spec, def) + register Display *dpy; + Colormap cmap; + char *spec; + XColor *def; +#endif +{ + register int n, i; + int r, g, b; + char c; + XcmsCCC ccc; + XcmsColor cmsColor; + + if (!spec) return(0); + n = strlen (spec); + if (*spec == '#') { + /* + * RGB + */ + spec++; + n--; + if (n != 3 && n != 6 && n != 9 && n != 12) + return (0); + n /= 3; + g = b = 0; + do { + r = g; + g = b; + b = 0; + for (i = n; --i >= 0; ) { + c = *spec++; + b <<= 4; + if (c >= '0' && c <= '9') + b |= c - '0'; + else if (c >= 'A' && c <= 'F') + b |= c - ('A' - 10); + else if (c >= 'a' && c <= 'f') + b |= c - ('a' - 10); + else return (0); + } + } while (*spec != '\0'); + n <<= 2; + n = 16 - n; + def->red = r << n; + def->green = g << n; + def->blue = b << n; + def->flags = DoRed | DoGreen | DoBlue; + return (1); + } + + + /* + * Let's Attempt to use Xcms and i18n approach to Parse Color + */ + if ((ccc = XcmsCCCOfColormap(dpy, cmap)) != (XcmsCCC)NULL) { + if (_XcmsResolveColorString(ccc, &spec, + &cmsColor, XcmsRGBFormat) >= XcmsSuccess) { + cmsColor.pixel = def->pixel; + _XcmsRGB_to_XColor(&cmsColor, def, 1); + return(1); + } + /* + * Otherwise we failed; or spec was changed with yet another + * name. Thus pass name to the X Server. + */ + } + + /* + * Xcms and i18n methods failed, so lets pass it to the server + * for parsing. + */ + { + xLookupColorReply reply; + register xLookupColorReq *req; + LockDisplay(dpy); + GetReq (LookupColor, req); + req->cmap = cmap; + req->nbytes = n = strlen(spec); + req->length += (n + 3) >> 2; + Data (dpy, spec, (long)n); + if (!_XReply (dpy, (xReply *) &reply, 0, xTrue)) { + UnlockDisplay(dpy); + SyncHandle(); + return (0); + } + def->red = reply.exactRed; + def->green = reply.exactGreen; + def->blue = reply.exactBlue; + def->flags = DoRed | DoGreen | DoBlue; + UnlockDisplay(dpy); + SyncHandle(); + return (1); + } +} diff --git a/src/ParseGeom.c b/src/ParseGeom.c new file mode 100644 index 00000000..6691c887 --- /dev/null +++ b/src/ParseGeom.c @@ -0,0 +1,186 @@ +/* $Xorg: ParseGeom.c,v 1.4 2001/02/09 02:03:35 xorgcvs Exp $ */ + +/* + +Copyright 1985, 1986, 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. + +*/ + +#include "Xlibint.h" +#include "Xutil.h" + +#ifdef notdef +/* + *Returns pointer to first char ins search which is also in what, else NULL. + */ +static char *strscan (search, what) +char *search, *what; +{ + int i, len = strlen (what); + char c; + + while ((c = *(search++)) != NULL) + for (i = 0; i < len; i++) + if (c == what [i]) + return (--search); + return (NULL); +} +#endif + +/* + * XParseGeometry parses strings of the form + * "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where + * width, height, xoffset, and yoffset are unsigned integers. + * Example: "=80x24+300-49" + * The equal sign is optional. + * It returns a bitmask that indicates which of the four values + * were actually found in the string. For each value found, + * the corresponding argument is updated; for each value + * not found, the corresponding argument is left unchanged. + */ + +static int +ReadInteger(string, NextString) +register char *string; +char **NextString; +{ + register int Result = 0; + int Sign = 1; + + if (*string == '+') + string++; + else if (*string == '-') + { + string++; + Sign = -1; + } + for (; (*string >= '0') && (*string <= '9'); string++) + { + Result = (Result * 10) + (*string - '0'); + } + *NextString = string; + if (Sign >= 0) + return (Result); + else + return (-Result); +} + +#if NeedFunctionPrototypes +int XParseGeometry ( +_Xconst char *string, +int *x, +int *y, +unsigned int *width, /* RETURN */ +unsigned int *height) /* RETURN */ +#else +int XParseGeometry (string, x, y, width, height) +char *string; +int *x, *y; +unsigned int *width, *height; /* RETURN */ +#endif +{ + int mask = NoValue; + register char *strind; + unsigned int tempWidth, tempHeight; + int tempX, tempY; + char *nextCharacter; + + if ( (string == NULL) || (*string == '\0')) return(mask); + if (*string == '=') + string++; /* ignore possible '=' at beg of geometry spec */ + + strind = (char *)string; + if (*strind != '+' && *strind != '-' && *strind != 'x') { + tempWidth = ReadInteger(strind, &nextCharacter); + if (strind == nextCharacter) + return (0); + strind = nextCharacter; + mask |= WidthValue; + } + + if (*strind == 'x' || *strind == 'X') { + strind++; + tempHeight = ReadInteger(strind, &nextCharacter); + if (strind == nextCharacter) + return (0); + strind = nextCharacter; + mask |= HeightValue; + } + + if ((*strind == '+') || (*strind == '-')) { + if (*strind == '-') { + strind++; + tempX = -ReadInteger(strind, &nextCharacter); + if (strind == nextCharacter) + return (0); + strind = nextCharacter; + mask |= XNegative; + + } + else + { strind++; + tempX = ReadInteger(strind, &nextCharacter); + if (strind == nextCharacter) + return(0); + strind = nextCharacter; + } + mask |= XValue; + if ((*strind == '+') || (*strind == '-')) { + if (*strind == '-') { + strind++; + tempY = -ReadInteger(strind, &nextCharacter); + if (strind == nextCharacter) + return(0); + strind = nextCharacter; + mask |= YNegative; + + } + else + { + strind++; + tempY = ReadInteger(strind, &nextCharacter); + if (strind == nextCharacter) + return(0); + strind = nextCharacter; + } + mask |= YValue; + } + } + + /* If strind isn't at the end of the string the it's an invalid + geometry specification. */ + + if (*strind != '\0') return (0); + + if (mask & XValue) + *x = tempX; + if (mask & YValue) + *y = tempY; + if (mask & WidthValue) + *width = tempWidth; + if (mask & HeightValue) + *height = tempHeight; + return (mask); +} diff --git a/src/PeekEvent.c b/src/PeekEvent.c new file mode 100644 index 00000000..ba597eeb --- /dev/null +++ b/src/PeekEvent.c @@ -0,0 +1,48 @@ +/* $Xorg: PeekEvent.c,v 1.4 2001/02/09 02:03:35 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#define NEED_EVENTS +#include "Xlibint.h" + +/* + * Return the next event in the queue, + * BUT do not remove it from the queue. + * If none found, flush and wait until there is an event to peek. + */ + +XPeekEvent (dpy, event) + register Display *dpy; + register XEvent *event; +{ + LockDisplay(dpy); + if (dpy->head == NULL) + _XReadEvents(dpy); + *event = (dpy->head)->event; + UnlockDisplay(dpy); + return 1; +} + diff --git a/src/PeekIfEv.c b/src/PeekIfEv.c new file mode 100644 index 00000000..6cb9d118 --- /dev/null +++ b/src/PeekIfEv.c @@ -0,0 +1,73 @@ +/* $Xorg: PeekIfEv.c,v 1.4 2001/02/09 02:03:35 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#define NEED_EVENTS +#include "Xlibint.h" + +/* + * return the next event in the queue that satisfies the predicate. + * BUT do not remove it from the queue. + * If none found, flush, and then wait until one satisfies the predicate. + */ + +XPeekIfEvent (dpy, event, predicate, arg) + register Display *dpy; + register XEvent *event; + Bool (*predicate)( +#if NeedNestedPrototypes + Display* /* display */, + XEvent* /* event */, + char* /* arg */ +#endif + ); + char *arg; +{ + register _XQEvent *prev, *qelt; + unsigned long qe_serial = 0; + + LockDisplay(dpy); + prev = NULL; + while (1) { + for (qelt = prev ? prev->next : dpy->head; + qelt; + prev = qelt, qelt = qelt->next) { + if(qelt->qserial_num > qe_serial + && (*predicate)(dpy, &qelt->event, arg)) { + *event = qelt->event; + UnlockDisplay(dpy); + return 0; + } + } + if (prev) + qe_serial = prev->qserial_num; + _XReadEvents(dpy); + if (prev && prev->qserial_num != qe_serial) + /* another thread has snatched this event */ + prev = NULL; + } +} + diff --git a/src/Pending.c b/src/Pending.c new file mode 100644 index 00000000..55e5e71b --- /dev/null +++ b/src/Pending.c @@ -0,0 +1,57 @@ +/* $Xorg: Pending.c,v 1.4 2001/02/09 02:03:35 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +/* Read in pending events if needed and return the number of queued events. */ + +int XEventsQueued (dpy, mode) + register Display *dpy; + int mode; +{ + int ret_val; + LockDisplay(dpy); + if (dpy->qlen || (mode == QueuedAlready)) + ret_val = dpy->qlen; + else + ret_val = _XEventsQueued (dpy, mode); + UnlockDisplay(dpy); + return ret_val; +} + +int XPending (dpy) + register Display *dpy; +{ + int ret_val; + LockDisplay(dpy); + if (dpy->qlen) + ret_val = dpy->qlen; + else + ret_val = _XEventsQueued (dpy, QueuedAfterFlush); + UnlockDisplay(dpy); + return ret_val; +} diff --git a/src/PixFormats.c b/src/PixFormats.c new file mode 100644 index 00000000..a8b74b1e --- /dev/null +++ b/src/PixFormats.c @@ -0,0 +1,60 @@ +/* $Xorg: PixFormats.c,v 1.4 2001/02/09 02:03:35 xorgcvs Exp $ */ +/* + +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. + +*/ + +#include "Xlibint.h" +#include <stdio.h> + +/* + * XListPixmapFormats - return info from connection setup + */ + +XPixmapFormatValues *XListPixmapFormats (dpy, count) + Display *dpy; + int *count; /* RETURN */ +{ + XPixmapFormatValues *formats = (XPixmapFormatValues *) + Xmalloc((unsigned) (dpy->nformats * sizeof (XPixmapFormatValues))); + + if (formats) { + register int i; + register XPixmapFormatValues *f; + register ScreenFormat *sf; + + /* + * copy data from internal Xlib data structure in display + */ + for (i = dpy->nformats, f = formats, sf = dpy->pixmap_format; i > 0; + i--, f++, sf++) { + f->depth = sf->depth; + f->bits_per_pixel = sf->bits_per_pixel; + f->scanline_pad = sf->scanline_pad; + } + + *count = dpy->nformats; + } + return formats; +} diff --git a/src/PmapBgnd.c b/src/PmapBgnd.c new file mode 100644 index 00000000..5a74410f --- /dev/null +++ b/src/PmapBgnd.c @@ -0,0 +1,45 @@ +/* $Xorg: PmapBgnd.c,v 1.4 2001/02/09 02:03:35 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XSetWindowBackgroundPixmap(dpy, w, pixmap) + register Display *dpy; + Window w; + Pixmap pixmap; +{ + register xChangeWindowAttributesReq *req; + LockDisplay (dpy); + GetReqExtra (ChangeWindowAttributes, 4, req); + req->window = w; + req->valueMask = CWBackPixmap; + OneDataCard32 (dpy, NEXTPTR(req,xChangeWindowAttributesReq), pixmap); + UnlockDisplay (dpy); + SyncHandle(); + return 1; +} + diff --git a/src/PmapBord.c b/src/PmapBord.c new file mode 100644 index 00000000..e33738ab --- /dev/null +++ b/src/PmapBord.c @@ -0,0 +1,45 @@ +/* $Xorg: PmapBord.c,v 1.4 2001/02/09 02:03:35 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XSetWindowBorderPixmap(dpy, w, pixmap) + register Display *dpy; + Window w; + Pixmap pixmap; +{ + register xChangeWindowAttributesReq *req; + LockDisplay(dpy); + GetReqExtra (ChangeWindowAttributes, 4, req); + req->window = w; + req->valueMask = CWBorderPixmap; + OneDataCard32 (dpy, NEXTPTR(req,xChangeWindowAttributesReq), pixmap); + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} + diff --git a/src/PolyReg.c b/src/PolyReg.c new file mode 100644 index 00000000..4d9a0b52 --- /dev/null +++ b/src/PolyReg.c @@ -0,0 +1,630 @@ +/* $Xorg: PolyReg.c,v 1.5 2001/02/09 02:03:35 xorgcvs Exp $ */ +/************************************************************************ + +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. + +************************************************************************/ + +#define LARGE_COORDINATE 1000000 +#define SMALL_COORDINATE -LARGE_COORDINATE + +#include "Xlibint.h" +#include "Xutil.h" +#include "region.h" +#include "poly.h" + +/* + * InsertEdgeInET + * + * Insert the given edge into the edge table. + * First we must find the correct bucket in the + * Edge table, then find the right slot in the + * bucket. Finally, we can insert it. + * + */ +static void +InsertEdgeInET(ET, ETE, scanline, SLLBlock, iSLLBlock) + EdgeTable *ET; + EdgeTableEntry *ETE; + int scanline; + ScanLineListBlock **SLLBlock; + int *iSLLBlock; +{ + register EdgeTableEntry *start, *prev; + register ScanLineList *pSLL, *pPrevSLL; + ScanLineListBlock *tmpSLLBlock; + + /* + * find the right bucket to put the edge into + */ + pPrevSLL = &ET->scanlines; + pSLL = pPrevSLL->next; + while (pSLL && (pSLL->scanline < scanline)) + { + pPrevSLL = pSLL; + pSLL = pSLL->next; + } + + /* + * reassign pSLL (pointer to ScanLineList) if necessary + */ + if ((!pSLL) || (pSLL->scanline > scanline)) + { + if (*iSLLBlock > SLLSPERBLOCK-1) + { + tmpSLLBlock = + (ScanLineListBlock *)Xmalloc(sizeof(ScanLineListBlock)); + (*SLLBlock)->next = tmpSLLBlock; + tmpSLLBlock->next = (ScanLineListBlock *)NULL; + *SLLBlock = tmpSLLBlock; + *iSLLBlock = 0; + } + pSLL = &((*SLLBlock)->SLLs[(*iSLLBlock)++]); + + pSLL->next = pPrevSLL->next; + pSLL->edgelist = (EdgeTableEntry *)NULL; + pPrevSLL->next = pSLL; + } + pSLL->scanline = scanline; + + /* + * now insert the edge in the right bucket + */ + prev = (EdgeTableEntry *)NULL; + start = pSLL->edgelist; + while (start && (start->bres.minor_axis < ETE->bres.minor_axis)) + { + prev = start; + start = start->next; + } + ETE->next = start; + + if (prev) + prev->next = ETE; + else + pSLL->edgelist = ETE; +} + +/* + * CreateEdgeTable + * + * This routine creates the edge table for + * scan converting polygons. + * The Edge Table (ET) looks like: + * + * EdgeTable + * -------- + * | ymax | ScanLineLists + * |scanline|-->------------>-------------->... + * -------- |scanline| |scanline| + * |edgelist| |edgelist| + * --------- --------- + * | | + * | | + * V V + * list of ETEs list of ETEs + * + * where ETE is an EdgeTableEntry data structure, + * and there is one ScanLineList per scanline at + * which an edge is initially entered. + * + */ + +static void +CreateETandAET(count, pts, ET, AET, pETEs, pSLLBlock) + register int count; + register XPoint *pts; + EdgeTable *ET; + EdgeTableEntry *AET; + register EdgeTableEntry *pETEs; + ScanLineListBlock *pSLLBlock; +{ + register XPoint *top, *bottom; + register XPoint *PrevPt, *CurrPt; + int iSLLBlock = 0; + int dy; + + if (count < 2) return; + + /* + * initialize the Active Edge Table + */ + AET->next = (EdgeTableEntry *)NULL; + AET->back = (EdgeTableEntry *)NULL; + AET->nextWETE = (EdgeTableEntry *)NULL; + AET->bres.minor_axis = SMALL_COORDINATE; + + /* + * initialize the Edge Table. + */ + ET->scanlines.next = (ScanLineList *)NULL; + ET->ymax = SMALL_COORDINATE; + ET->ymin = LARGE_COORDINATE; + pSLLBlock->next = (ScanLineListBlock *)NULL; + + PrevPt = &pts[count-1]; + + /* + * for each vertex in the array of points. + * In this loop we are dealing with two vertices at + * a time -- these make up one edge of the polygon. + */ + while (count--) + { + CurrPt = pts++; + + /* + * find out which point is above and which is below. + */ + if (PrevPt->y > CurrPt->y) + { + bottom = PrevPt, top = CurrPt; + pETEs->ClockWise = 0; + } + else + { + bottom = CurrPt, top = PrevPt; + pETEs->ClockWise = 1; + } + + /* + * don't add horizontal edges to the Edge table. + */ + if (bottom->y != top->y) + { + pETEs->ymax = bottom->y-1; /* -1 so we don't get last scanline */ + + /* + * initialize integer edge algorithm + */ + dy = bottom->y - top->y; + BRESINITPGONSTRUCT(dy, top->x, bottom->x, pETEs->bres); + + InsertEdgeInET(ET, pETEs, top->y, &pSLLBlock, &iSLLBlock); + + if (PrevPt->y > ET->ymax) + ET->ymax = PrevPt->y; + if (PrevPt->y < ET->ymin) + ET->ymin = PrevPt->y; + pETEs++; + } + + PrevPt = CurrPt; + } +} + +/* + * loadAET + * + * This routine moves EdgeTableEntries from the + * EdgeTable into the Active Edge Table, + * leaving them sorted by smaller x coordinate. + * + */ + +static void +loadAET(AET, ETEs) + register EdgeTableEntry *AET, *ETEs; +{ + register EdgeTableEntry *pPrevAET; + register EdgeTableEntry *tmp; + + pPrevAET = AET; + AET = AET->next; + while (ETEs) + { + while (AET && (AET->bres.minor_axis < ETEs->bres.minor_axis)) + { + pPrevAET = AET; + AET = AET->next; + } + tmp = ETEs->next; + ETEs->next = AET; + if (AET) + AET->back = ETEs; + ETEs->back = pPrevAET; + pPrevAET->next = ETEs; + pPrevAET = ETEs; + + ETEs = tmp; + } +} + +/* + * computeWAET + * + * This routine links the AET by the + * nextWETE (winding EdgeTableEntry) link for + * use by the winding number rule. The final + * Active Edge Table (AET) might look something + * like: + * + * AET + * ---------- --------- --------- + * |ymax | |ymax | |ymax | + * | ... | |... | |... | + * |next |->|next |->|next |->... + * |nextWETE| |nextWETE| |nextWETE| + * --------- --------- ^-------- + * | | | + * V-------------------> V---> ... + * + */ +static void +computeWAET(AET) + register EdgeTableEntry *AET; +{ + register EdgeTableEntry *pWETE; + register int inside = 1; + register int isInside = 0; + + AET->nextWETE = (EdgeTableEntry *)NULL; + pWETE = AET; + AET = AET->next; + while (AET) + { + if (AET->ClockWise) + isInside++; + else + isInside--; + + if ((!inside && !isInside) || + ( inside && isInside)) + { + pWETE->nextWETE = AET; + pWETE = AET; + inside = !inside; + } + AET = AET->next; + } + pWETE->nextWETE = (EdgeTableEntry *)NULL; +} + +/* + * InsertionSort + * + * Just a simple insertion sort using + * pointers and back pointers to sort the Active + * Edge Table. + * + */ + +static int +InsertionSort(AET) + register EdgeTableEntry *AET; +{ + register EdgeTableEntry *pETEchase; + register EdgeTableEntry *pETEinsert; + register EdgeTableEntry *pETEchaseBackTMP; + register int changed = 0; + + AET = AET->next; + while (AET) + { + pETEinsert = AET; + pETEchase = AET; + while (pETEchase->back->bres.minor_axis > AET->bres.minor_axis) + pETEchase = pETEchase->back; + + AET = AET->next; + if (pETEchase != pETEinsert) + { + pETEchaseBackTMP = pETEchase->back; + pETEinsert->back->next = AET; + if (AET) + AET->back = pETEinsert->back; + pETEinsert->next = pETEchase; + pETEchase->back->next = pETEinsert; + pETEchase->back = pETEinsert; + pETEinsert->back = pETEchaseBackTMP; + changed = 1; + } + } + return(changed); +} + +/* + * Clean up our act. + */ +static void +FreeStorage(pSLLBlock) + register ScanLineListBlock *pSLLBlock; +{ + register ScanLineListBlock *tmpSLLBlock; + + while (pSLLBlock) + { + tmpSLLBlock = pSLLBlock->next; + Xfree((char *)pSLLBlock); + pSLLBlock = tmpSLLBlock; + } +} + +/* + * Create an array of rectangles from a list of points. + * If indeed these things (POINTS, RECTS) are the same, + * then this proc is still needed, because it allocates + * storage for the array, which was allocated on the + * stack by the calling procedure. + * + */ +static int PtsToRegion(numFullPtBlocks, iCurPtBlock, FirstPtBlock, reg) + register int numFullPtBlocks, iCurPtBlock; + POINTBLOCK *FirstPtBlock; + REGION *reg; +{ + register BOX *rects; + register XPoint *pts; + register POINTBLOCK *CurPtBlock; + register int i; + register BOX *extents; + register int numRects; + BOX *prevRects = reg->rects; + + extents = ®->extents; + + numRects = ((numFullPtBlocks * NUMPTSTOBUFFER) + iCurPtBlock) >> 1; + + if (!(reg->rects = (BOX *)Xrealloc((char *)reg->rects, + (unsigned) (sizeof(BOX) * numRects)))) { + Xfree(prevRects); + return(0); + } + + reg->size = numRects; + CurPtBlock = FirstPtBlock; + rects = reg->rects - 1; + numRects = 0; + extents->x1 = MAXSHORT, extents->x2 = MINSHORT; + + for ( ; numFullPtBlocks >= 0; numFullPtBlocks--) { + /* the loop uses 2 points per iteration */ + i = NUMPTSTOBUFFER >> 1; + if (!numFullPtBlocks) + i = iCurPtBlock >> 1; + for (pts = CurPtBlock->pts; i--; pts += 2) { + if (pts->x == pts[1].x) + continue; + if (numRects && pts->x == rects->x1 && pts->y == rects->y2 && + pts[1].x == rects->x2 && + (numRects == 1 || rects[-1].y1 != rects->y1) && + (i && pts[2].y > pts[1].y)) { + rects->y2 = pts[1].y + 1; + continue; + } + numRects++; + rects++; + rects->x1 = pts->x; rects->y1 = pts->y; + rects->x2 = pts[1].x; rects->y2 = pts[1].y + 1; + if (rects->x1 < extents->x1) + extents->x1 = rects->x1; + if (rects->x2 > extents->x2) + extents->x2 = rects->x2; + } + CurPtBlock = CurPtBlock->next; + } + + if (numRects) { + extents->y1 = reg->rects->y1; + extents->y2 = rects->y2; + } else { + extents->x1 = 0; + extents->y1 = 0; + extents->x2 = 0; + extents->y2 = 0; + } + reg->numRects = numRects; + + return(TRUE); +} + +/* + * polytoregion + * + * Scan converts a polygon by returning a run-length + * encoding of the resultant bitmap -- the run-length + * encoding is in the form of an array of rectangles. + */ +Region +XPolygonRegion(Pts, Count, rule) + int Count; /* number of pts */ + XPoint *Pts; /* the pts */ + int rule; /* winding rule */ +{ + Region region; + register EdgeTableEntry *pAET; /* Active Edge Table */ + register int y; /* current scanline */ + register int iPts = 0; /* number of pts in buffer */ + register EdgeTableEntry *pWETE; /* Winding Edge Table Entry*/ + register ScanLineList *pSLL; /* current scanLineList */ + register XPoint *pts; /* output buffer */ + EdgeTableEntry *pPrevAET; /* ptr to previous AET */ + EdgeTable ET; /* header node for ET */ + EdgeTableEntry AET; /* header node for AET */ + EdgeTableEntry *pETEs; /* EdgeTableEntries pool */ + ScanLineListBlock SLLBlock; /* header for scanlinelist */ + int fixWAET = FALSE; + POINTBLOCK FirstPtBlock, *curPtBlock; /* PtBlock buffers */ + POINTBLOCK *tmpPtBlock; + int numFullPtBlocks = 0; + + if (! (region = XCreateRegion())) return (Region) NULL; + + /* special case a rectangle */ + pts = Pts; + if (((Count == 4) || + ((Count == 5) && (pts[4].x == pts[0].x) && (pts[4].y == pts[0].y))) && + (((pts[0].y == pts[1].y) && + (pts[1].x == pts[2].x) && + (pts[2].y == pts[3].y) && + (pts[3].x == pts[0].x)) || + ((pts[0].x == pts[1].x) && + (pts[1].y == pts[2].y) && + (pts[2].x == pts[3].x) && + (pts[3].y == pts[0].y)))) { + region->extents.x1 = min(pts[0].x, pts[2].x); + region->extents.y1 = min(pts[0].y, pts[2].y); + region->extents.x2 = max(pts[0].x, pts[2].x); + region->extents.y2 = max(pts[0].y, pts[2].y); + if ((region->extents.x1 != region->extents.x2) && + (region->extents.y1 != region->extents.y2)) { + region->numRects = 1; + *(region->rects) = region->extents; + } + return(region); + } + + if (! (pETEs = (EdgeTableEntry *) + Xmalloc((unsigned) (sizeof(EdgeTableEntry) * Count)))) + return (Region) NULL; + + pts = FirstPtBlock.pts; + CreateETandAET(Count, Pts, &ET, &AET, pETEs, &SLLBlock); + pSLL = ET.scanlines.next; + curPtBlock = &FirstPtBlock; + + if (rule == EvenOddRule) { + /* + * for each scanline + */ + for (y = ET.ymin; y < ET.ymax; y++) { + /* + * Add a new edge to the active edge table when we + * get to the next edge. + */ + if (pSLL != NULL && y == pSLL->scanline) { + loadAET(&AET, pSLL->edgelist); + pSLL = pSLL->next; + } + pPrevAET = &AET; + pAET = AET.next; + + /* + * for each active edge + */ + while (pAET) { + pts->x = pAET->bres.minor_axis, pts->y = y; + pts++, iPts++; + + /* + * send out the buffer + */ + if (iPts == NUMPTSTOBUFFER) { + tmpPtBlock = (POINTBLOCK *)Xmalloc(sizeof(POINTBLOCK)); + curPtBlock->next = tmpPtBlock; + curPtBlock = tmpPtBlock; + pts = curPtBlock->pts; + numFullPtBlocks++; + iPts = 0; + } + EVALUATEEDGEEVENODD(pAET, pPrevAET, y); + } + (void) InsertionSort(&AET); + } + } + else { + /* + * for each scanline + */ + for (y = ET.ymin; y < ET.ymax; y++) { + /* + * Add a new edge to the active edge table when we + * get to the next edge. + */ + if (pSLL != NULL && y == pSLL->scanline) { + loadAET(&AET, pSLL->edgelist); + computeWAET(&AET); + pSLL = pSLL->next; + } + pPrevAET = &AET; + pAET = AET.next; + pWETE = pAET; + + /* + * for each active edge + */ + while (pAET) { + /* + * add to the buffer only those edges that + * are in the Winding active edge table. + */ + if (pWETE == pAET) { + pts->x = pAET->bres.minor_axis, pts->y = y; + pts++, iPts++; + + /* + * send out the buffer + */ + if (iPts == NUMPTSTOBUFFER) { + tmpPtBlock = (POINTBLOCK *)Xmalloc(sizeof(POINTBLOCK)); + curPtBlock->next = tmpPtBlock; + curPtBlock = tmpPtBlock; + pts = curPtBlock->pts; + numFullPtBlocks++; iPts = 0; + } + pWETE = pWETE->nextWETE; + } + EVALUATEEDGEWINDING(pAET, pPrevAET, y, fixWAET); + } + + /* + * recompute the winding active edge table if + * we just resorted or have exited an edge. + */ + if (InsertionSort(&AET) || fixWAET) { + computeWAET(&AET); + fixWAET = FALSE; + } + } + } + FreeStorage(SLLBlock.next); + (void) PtsToRegion(numFullPtBlocks, iPts, &FirstPtBlock, region); + for (curPtBlock = FirstPtBlock.next; --numFullPtBlocks >= 0;) { + tmpPtBlock = curPtBlock->next; + Xfree((char *)curPtBlock); + curPtBlock = tmpPtBlock; + } + Xfree((char *)pETEs); + return(region); +} diff --git a/src/PolyTxt.c b/src/PolyTxt.c new file mode 100644 index 00000000..c90a7b04 --- /dev/null +++ b/src/PolyTxt.c @@ -0,0 +1,230 @@ +/* $Xorg: PolyTxt.c,v 1.4 2001/02/09 02:03:35 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XDrawText(dpy, d, gc, x, y, items, nitems) + register Display *dpy; + Drawable d; + GC gc; + int x, y; + XTextItem *items; + int nitems; +{ + register int i; + register XTextItem *item; + int length = 0; + register xPolyText8Req *req; + + LockDisplay(dpy); + FlushGC(dpy, gc); + GetReq (PolyText8, req); + req->drawable = d; + req->gc = gc->gid; + req->x = x; + req->y = y; + + item = items; + for (i=0; i < nitems; i++) { + if (item->font) + length += 5; /* a 255 byte, plus size of Font id */ + if (item->delta) + { + if (item->delta > 0) + { + length += SIZEOF(xTextElt) * ((item->delta + 126) / 127); + } + else + { + length += SIZEOF(xTextElt) * ((-item->delta + 127) / 128); + } + } + if (item->nchars > 0) + { + length += SIZEOF(xTextElt) * ((item->nchars + 253) / 254 - 1); + if (!item->delta) length += SIZEOF(xTextElt); + length += item->nchars; + } + item++; + } + + req->length += (length + 3)>>2; /* convert to number of 32-bit words */ + + + /* + * If the entire request does not fit into the remaining space in the + * buffer, flush the buffer first. If the request does fit into the + * empty buffer, then we won't have to flush it at the end to keep + * the buffer 32-bit aligned. + */ + + if (dpy->bufptr + length > dpy->bufmax) + _XFlush (dpy); + + item = items; + for (i=0; i< nitems; i++) { + + if (item->font) { + /* to mark a font shift, write a 255 byte followed by + the 4 bytes of font ID, big-end first */ + register unsigned char *f; + BufAlloc (unsigned char *, f, 5); + + f[0] = 255; + f[1] = (item->font & 0xff000000) >> 24; + f[2] = (item->font & 0x00ff0000) >> 16; + f[3] = (item->font & 0x0000ff00) >> 8; + f[4] = item->font & 0x000000ff; + + /* update GC shadow */ + gc->values.font = item->font; + } + + { + int nbytes = SIZEOF(xTextElt); + int PartialNChars = item->nchars; + int PartialDelta = item->delta; + /* register xTextElt *elt; */ + int FirstTimeThrough = True; + char *CharacterOffset = item->chars; + char *tbuf; + + while((PartialDelta < -128) || (PartialDelta > 127)) + { + int nb = SIZEOF(xTextElt); + + BufAlloc (char *, tbuf, nb); + *tbuf = 0; /* elt->len */ + if (PartialDelta > 0 ) + { + *(tbuf+1) = 127; /* elt->delta */ + PartialDelta = PartialDelta - 127; + } + else + { + /* -128 = 0x8, need to be careful of signed chars... */ + *((unsigned char *)(tbuf+1)) = 0x80; /* elt->delta */ + PartialDelta = PartialDelta + 128; + } + } + if (PartialDelta) + { + BufAlloc (char *, tbuf , nbytes); + *tbuf = 0; /* elt->len */ + *(tbuf+1) = PartialDelta; /* elt->delta */ + } + while(PartialNChars > 254) + { + nbytes = 254; + if (FirstTimeThrough) + { + FirstTimeThrough = False; + if (!item->delta) + { + nbytes += SIZEOF(xTextElt); + BufAlloc (char *, tbuf, nbytes); + *(tbuf+1) = 0; /* elt->delta */ + } + else + { + char *DummyChar; + BufAlloc(char *, DummyChar, nbytes); + } + } + else + { + nbytes += SIZEOF(xTextElt); + BufAlloc (char *, tbuf, nbytes); + *(tbuf+1) = 0; /* elt->delta */ + } + /* watch out for signs on chars */ + *(unsigned char *)tbuf = 254; /* elt->len */ + memcpy (tbuf+2 , CharacterOffset, 254); + PartialNChars = PartialNChars - 254; + CharacterOffset += 254; + + } + if (PartialNChars) + { + nbytes = PartialNChars; + if (FirstTimeThrough) + { + FirstTimeThrough = False; + if (!item->delta) + { + nbytes += SIZEOF(xTextElt); + BufAlloc (char *, tbuf, nbytes); + *(tbuf+1) = 0; /* elt->delta */ + } + else + { + char *DummyChar; + BufAlloc(char *, DummyChar, nbytes); + } + } + else + { + nbytes += SIZEOF(xTextElt); + BufAlloc (char *, tbuf, nbytes); + *(tbuf+1) = 0; /* elt->delta */ + } + *tbuf = PartialNChars; /* elt->len */ + memcpy (tbuf+2 , CharacterOffset, PartialNChars); + } + } + item++; + } + + /* Pad request out to a 32-bit boundary */ + + if (length &= 3) { + char *pad; + /* + * BufAlloc is a macro that uses its last argument more than + * once, otherwise I'd write "BufAlloc (char *, pad, 4-length)" + */ + length = 4 - length; + BufAlloc (char *, pad, length); + /* + * if there are 3 bytes of padding, the first byte MUST be 0 + * so the pad bytes aren't mistaken for a final xTextElt + */ + *pad = 0; + } + + /* + * If the buffer pointer is not now pointing to a 32-bit boundary, + * we must flush the buffer so that it does point to a 32-bit boundary + * at the end of this routine. + */ + + if ((dpy->bufptr - dpy->buffer) & 3) + _XFlush (dpy); + UnlockDisplay(dpy); + SyncHandle(); + return 0; + } diff --git a/src/PolyTxt16.c b/src/PolyTxt16.c new file mode 100644 index 00000000..e75ad5c4 --- /dev/null +++ b/src/PolyTxt16.c @@ -0,0 +1,264 @@ +/* $Xorg: PolyTxt16.c,v 1.4 2001/02/09 02:03:35 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XDrawText16(dpy, d, gc, x, y, items, nitems) + register Display *dpy; + Drawable d; + GC gc; + int x, y; + XTextItem16 *items; + int nitems; +{ + register int i; + register XTextItem16 *item; + int length = 0; + register xPolyText16Req *req; + + LockDisplay(dpy); + FlushGC(dpy, gc); + GetReq (PolyText16, req); + req->drawable = d; + req->gc = gc->gid; + req->x = x; + req->y = y; + + item = items; + for (i=0; i < nitems; i++) { + if (item->font) + length += 5; /* a 255 byte, plus size of Font id */ + if (item->delta) + { + if (item->delta > 0) + { + length += SIZEOF(xTextElt) * ((item->delta + 126) / 127); + } + else + { + length += SIZEOF(xTextElt) * ((-item->delta + 127) / 128); + } + } + if (item->nchars > 0) + { + length += SIZEOF(xTextElt) * ((item->nchars + 253) / 254 - 1); + if (!item->delta) length += SIZEOF(xTextElt); + length += item->nchars << 1; + } + item++; + } + + req->length += (length + 3)>>2; /* convert to number of 32-bit words */ + + + /* + * If the entire request does not fit into the remaining space in the + * buffer, flush the buffer first. If the request does fit into the + * empty buffer, then we won't have to flush it at the end to keep + * the buffer 32-bit aligned. + */ + + if (dpy->bufptr + length > dpy->bufmax) + _XFlush (dpy); + + item = items; + for (i=0; i< nitems; i++) { + + if (item->font) { + /* to mark a font shift, write a 255 byte followed by + the 4 bytes of font ID, big-end first */ + register unsigned char *f; + BufAlloc (unsigned char *, f, 5); + + f[0] = 255; + f[1] = (item->font & 0xff000000) >> 24; + f[2] = (item->font & 0x00ff0000) >> 16; + f[3] = (item->font & 0x0000ff00) >> 8; + f[4] = item->font & 0x000000ff; + + /* update GC shadow */ + gc->values.font = item->font; + } + + { + int nbytes = SIZEOF(xTextElt); + int PartialNChars = item->nchars; + int PartialDelta = item->delta; + register xTextElt *elt; + int FirstTimeThrough = True; + XChar2b *CharacterOffset = item->chars; + + while((PartialDelta < -128) || (PartialDelta > 127)) + { + int nb = SIZEOF(xTextElt); + + BufAlloc (xTextElt *, elt, nb); + elt->len = 0; + if (PartialDelta > 0 ) + { + elt->delta = 127; + PartialDelta = PartialDelta - 127; + } + else + { + elt->delta = -128; + PartialDelta = PartialDelta + 128; + } + } + if (PartialDelta) + { + BufAlloc (xTextElt *, elt, nbytes); + elt->len = 0; + elt->delta = PartialDelta; + } + while(PartialNChars > 254) + { + nbytes = 254 * 2; + if (FirstTimeThrough) + { + FirstTimeThrough = False; + if (!item->delta) + { + nbytes += SIZEOF(xTextElt); + BufAlloc (xTextElt *, elt, nbytes); + elt->delta = 0; + } + else + { + char *DummyChar; + BufAlloc(char *, DummyChar, nbytes); +#ifdef lint + DummyChar = DummyChar; +#endif + } + } + else + { + nbytes += SIZEOF(xTextElt); + BufAlloc (xTextElt *, elt, nbytes); + elt->delta = 0; + } + elt->len = 254; + +#if defined(MUSTCOPY) || defined(MUSTCOPY2B) + { + register int i; + register unsigned char *cp; + for (i = 0, cp = ((unsigned char *)elt) + 2; i < 254; i++) { + *cp++ = CharacterOffset[i].byte1; + *cp++ = CharacterOffset[i].byte2; + } + } +#else + memcpy ((char *) (elt + 1), (char *)CharacterOffset, 254 * 2); +#endif + PartialNChars = PartialNChars - 254; + CharacterOffset += 254; + + } + if (PartialNChars) + { + nbytes = PartialNChars * 2; + if (FirstTimeThrough) + { + FirstTimeThrough = False; + if (!item->delta) + { + nbytes += SIZEOF(xTextElt); + BufAlloc (xTextElt *, elt, nbytes); + elt->delta = 0; + } + else + { + char *DummyChar; + BufAlloc(char *, DummyChar, nbytes); +#ifdef lint + DummyChar = DummyChar; +#endif + } + } + else + { + nbytes += SIZEOF(xTextElt); + BufAlloc (xTextElt *, elt, nbytes); + elt->delta = 0; + } + elt->len = PartialNChars; + +#if defined(MUSTCOPY) || defined(MUSTCOPY2B) + { + register int i; + register unsigned char *cp; + for (i = 0, cp = ((unsigned char *)elt) + 2; i < PartialNChars; + i++) { + *cp++ = CharacterOffset[i].byte1; + *cp++ = CharacterOffset[i].byte2; + } + } +#else + memcpy ((char *) (elt + 1), (char *)CharacterOffset, + PartialNChars * +2); +#endif + } + } + item++; + } + + /* Pad request out to a 32-bit boundary */ + + if (length &= 3) { + char *pad; + /* + * BufAlloc is a macro that uses its last argument more than + * once, otherwise I'd write "BufAlloc (char *, pad, 4-length)" + */ + length = 4 - length; + BufAlloc (char *, pad, length); + /* + * if there are 3 bytes of padding, the first byte MUST be 0 + * so the pad bytes aren't mistaken for a final xTextElt + */ + *pad = 0; + } + + /* + * If the buffer pointer is not now pointing to a 32-bit boundary, + * we must flush the buffer so that it does point to a 32-bit boundary + * at the end of this routine. + */ + + if ((dpy->bufptr - dpy->buffer) & 3) + _XFlush (dpy); + + UnlockDisplay(dpy); + SyncHandle(); + return 1; + } + + + diff --git a/src/PropAlloc.c b/src/PropAlloc.c new file mode 100644 index 00000000..9b95436e --- /dev/null +++ b/src/PropAlloc.c @@ -0,0 +1,73 @@ +/* $Xorg: PropAlloc.c,v 1.5 2001/02/09 02:03:35 xorgcvs Exp $ */ +/* + +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. + +*/ + +#include "Xlibint.h" +#include "Xutil.h" +#include <stdio.h> + + +/* + * Routines for allocating space for structures that are expected to get + * longer at some point. + */ + +XSizeHints *XAllocSizeHints () +{ + return ((XSizeHints *) Xcalloc (1, (unsigned) sizeof (XSizeHints))); +} + + +XStandardColormap *XAllocStandardColormap () +{ + return ((XStandardColormap *) + Xcalloc (1, (unsigned) sizeof (XStandardColormap))); +} + + +XWMHints *XAllocWMHints () +{ + return ((XWMHints *) Xcalloc (1, (unsigned) sizeof (XWMHints))); +} + + +XClassHint *XAllocClassHint () +{ + register XClassHint *h; + + if ((h = (XClassHint *) Xcalloc (1, (unsigned) sizeof (XClassHint)))) + h->res_name = h->res_class = NULL; + + return h; +} + + +XIconSize *XAllocIconSize () +{ + return ((XIconSize *) Xcalloc (1, (unsigned) sizeof (XIconSize))); +} + + diff --git a/src/PutBEvent.c b/src/PutBEvent.c new file mode 100644 index 00000000..21f57bb6 --- /dev/null +++ b/src/PutBEvent.c @@ -0,0 +1,59 @@ +/* $Xorg: PutBEvent.c,v 1.4 2001/02/09 02:03:35 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +/* XPutBackEvent puts an event back at the head of the queue. */ +#define NEED_EVENTS +#include "Xlibint.h" + +XPutBackEvent (dpy, event) + register Display *dpy; + register XEvent *event; + { + register _XQEvent *qelt; + + LockDisplay(dpy); + if (!dpy->qfree) { + if ((dpy->qfree = (_XQEvent *) Xmalloc (sizeof (_XQEvent))) == NULL) { + UnlockDisplay(dpy); + return 0; + } + dpy->qfree->next = NULL; + } + qelt = dpy->qfree; + dpy->qfree = qelt->next; + qelt->qserial_num = dpy->next_event_serial_num++; + qelt->next = dpy->head; + qelt->event = *event; + dpy->head = qelt; + if (dpy->tail == NULL) + dpy->tail = qelt; + dpy->qlen++; + UnlockDisplay(dpy); + return 0; + } diff --git a/src/PutImage.c b/src/PutImage.c new file mode 100644 index 00000000..8c13a097 --- /dev/null +++ b/src/PutImage.c @@ -0,0 +1,998 @@ +/* $Xorg: PutImage.c,v 1.4 2001/02/09 02:03:35 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" +#include "Xutil.h" +#include <stdio.h> + +#ifdef __STDC__ +#define Const const +#else +#define Const /**/ +#endif +#if defined(__STDC__) && ((defined(sun) && defined(SVR4)) || defined(WIN32)) +#define RConst /**/ +#else +#define RConst Const +#endif + +/* assumes pad is a power of 2 */ +#define ROUNDUP(nbytes, pad) (((nbytes) + ((pad) - 1)) & ~(long)((pad) - 1)) + +static unsigned char Const _reverse_byte[0x100] = { + 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, + 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, + 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, + 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, + 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, + 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, + 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, + 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, + 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, + 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, + 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, + 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, + 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, + 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, + 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, + 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, + 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, + 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, + 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, + 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, + 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, + 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, + 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, + 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, + 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, + 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, + 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, + 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, + 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, + 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, + 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, + 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff +}; + +static unsigned char Const _reverse_nibs[0x100] = { + 0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, + 0x80, 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0, + 0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71, + 0x81, 0x91, 0xa1, 0xb1, 0xc1, 0xd1, 0xe1, 0xf1, + 0x02, 0x12, 0x22, 0x32, 0x42, 0x52, 0x62, 0x72, + 0x82, 0x92, 0xa2, 0xb2, 0xc2, 0xd2, 0xe2, 0xf2, + 0x03, 0x13, 0x23, 0x33, 0x43, 0x53, 0x63, 0x73, + 0x83, 0x93, 0xa3, 0xb3, 0xc3, 0xd3, 0xe3, 0xf3, + 0x04, 0x14, 0x24, 0x34, 0x44, 0x54, 0x64, 0x74, + 0x84, 0x94, 0xa4, 0xb4, 0xc4, 0xd4, 0xe4, 0xf4, + 0x05, 0x15, 0x25, 0x35, 0x45, 0x55, 0x65, 0x75, + 0x85, 0x95, 0xa5, 0xb5, 0xc5, 0xd5, 0xe5, 0xf5, + 0x06, 0x16, 0x26, 0x36, 0x46, 0x56, 0x66, 0x76, + 0x86, 0x96, 0xa6, 0xb6, 0xc6, 0xd6, 0xe6, 0xf6, + 0x07, 0x17, 0x27, 0x37, 0x47, 0x57, 0x67, 0x77, + 0x87, 0x97, 0xa7, 0xb7, 0xc7, 0xd7, 0xe7, 0xf7, + 0x08, 0x18, 0x28, 0x38, 0x48, 0x58, 0x68, 0x78, + 0x88, 0x98, 0xa8, 0xb8, 0xc8, 0xd8, 0xe8, 0xf8, + 0x09, 0x19, 0x29, 0x39, 0x49, 0x59, 0x69, 0x79, + 0x89, 0x99, 0xa9, 0xb9, 0xc9, 0xd9, 0xe9, 0xf9, + 0x0a, 0x1a, 0x2a, 0x3a, 0x4a, 0x5a, 0x6a, 0x7a, + 0x8a, 0x9a, 0xaa, 0xba, 0xca, 0xda, 0xea, 0xfa, + 0x0b, 0x1b, 0x2b, 0x3b, 0x4b, 0x5b, 0x6b, 0x7b, + 0x8b, 0x9b, 0xab, 0xbb, 0xcb, 0xdb, 0xeb, 0xfb, + 0x0c, 0x1c, 0x2c, 0x3c, 0x4c, 0x5c, 0x6c, 0x7c, + 0x8c, 0x9c, 0xac, 0xbc, 0xcc, 0xdc, 0xec, 0xfc, + 0x0d, 0x1d, 0x2d, 0x3d, 0x4d, 0x5d, 0x6d, 0x7d, + 0x8d, 0x9d, 0xad, 0xbd, 0xcd, 0xdd, 0xed, 0xfd, + 0x0e, 0x1e, 0x2e, 0x3e, 0x4e, 0x5e, 0x6e, 0x7e, + 0x8e, 0x9e, 0xae, 0xbe, 0xce, 0xde, 0xee, 0xfe, + 0x0f, 0x1f, 0x2f, 0x3f, 0x4f, 0x5f, 0x6f, 0x7f, + 0x8f, 0x9f, 0xaf, 0xbf, 0xcf, 0xdf, 0xef, 0xff +}; + + +_XReverse_Bytes (bpt, nb) + register unsigned char *bpt; + register int nb; +{ + do { + *bpt = _reverse_byte[*bpt]; + bpt++; + } while (--nb > 0); + return 0; +} + + +/* XXX the following functions are declared int instead of void because various + * compilers and lints complain about later initialization of SwapFunc and/or + * (swapfunc == NoSwap) when void is used. + */ + +/*ARGSUSED*/ +static void +NoSwap (src, dest, srclen, srcinc, destinc, height, half_order) + register unsigned char *src, *dest; + long srclen, srcinc, destinc; + unsigned int height; + int half_order; +{ + long h = height; + + if (srcinc == destinc) + memcpy((char *)dest, (char *)src, (int)(srcinc * (h - 1) + srclen)); + else + for (; --h >= 0; src += srcinc, dest += destinc) + memcpy((char *)dest, (char *)src, (int)srclen); +} + +static void +SwapTwoBytes (src, dest, srclen, srcinc, destinc, height, half_order) + register unsigned char *src, *dest; + long srclen, srcinc, destinc; + unsigned int height; + int half_order; +{ + long length = ROUNDUP(srclen, 2); + register long h, n; + + srcinc -= length; + destinc -= length; + for (h = height; --h >= 0; src += srcinc, dest += destinc) { + if ((h == 0) && (srclen != length)) { + length -= 2; + if (half_order == MSBFirst) + *(dest + length) = *(src + length + 1); + else + *(dest + length + 1) = *(src + length); + } + for (n = length; n > 0; n -= 2, src += 2) { + *dest++ = *(src + 1); + *dest++ = *src; + } + } +} + +static void +SwapThreeBytes (src, dest, srclen, srcinc, destinc, height, byte_order) + register unsigned char *src, *dest; + long srclen, srcinc, destinc; + unsigned int height; + int byte_order; +{ + long length = ((srclen + 2) / 3) * 3; + register long h, n; + + srcinc -= length; + destinc -= length; + for (h = height; --h >= 0; src += srcinc, dest += destinc) { + if ((h == 0) && (srclen != length)) { + length -= 3; + if ((srclen - length) == 2) + *(dest + length + 1) = *(src + length + 1); + if (byte_order == MSBFirst) + *(dest + length) = *(src + length + 2); + else + *(dest + length + 2) = *(src + length); + } + for (n = length; n > 0; n -= 3, src += 3) { + *dest++ = *(src + 2); + *dest++ = *(src + 1); + *dest++ = *src; + } + } +} + +static void +SwapFourBytes (src, dest, srclen, srcinc, destinc, height, half_order) + register unsigned char *src, *dest; + long srclen, srcinc, destinc; + unsigned int height; + int half_order; +{ + long length = ROUNDUP(srclen, 4); + register long h, n; + + srcinc -= length; + destinc -= length; + for (h = height; --h >= 0; src += srcinc, dest += destinc) { + if ((h == 0) && (srclen != length)) { + length -= 4; + if (half_order == MSBFirst) + *(dest + length) = *(src + length + 3); + if (((half_order == LSBFirst) && ((srclen - length) == 3)) || + ((half_order == MSBFirst) && (srclen & 2))) + *(dest + length + 1) = *(src + length + 2); + if (((half_order == MSBFirst) && ((srclen - length) == 3)) || + ((half_order == LSBFirst) && (srclen & 2))) + *(dest + length + 2) = *(src + length + 1); + if (half_order == LSBFirst) + *(dest + length + 3) = *(src + length); + } + for (n = length; n > 0; n -= 4, src += 4) { + *dest++ = *(src + 3); + *dest++ = *(src + 2); + *dest++ = *(src + 1); + *dest++ = *src; + } + } +} + +static void +SwapWords (src, dest, srclen, srcinc, destinc, height, half_order) + register unsigned char *src, *dest; + long srclen, srcinc, destinc; + unsigned int height; + int half_order; +{ + long length = ROUNDUP(srclen, 4); + register long h, n; + + srcinc -= length; + destinc -= length; + for (h = height; --h >= 0; src += srcinc, dest += destinc) { + if ((h == 0) && (srclen != length)) { + length -= 4; + if (half_order == MSBFirst) + *(dest + length + 1) = *(src + length + 3); + if (((half_order == LSBFirst) && ((srclen - length) == 3)) || + ((half_order == MSBFirst) && (srclen & 2))) + *(dest + length) = *(src + length + 2); + if (((half_order == MSBFirst) && ((srclen - length) == 3)) || + ((half_order == LSBFirst) && (srclen & 2))) + *(dest + length + 3) = *(src + length + 1); + if (half_order == LSBFirst) + *(dest + length + 2) = *(src + length); + } + for (n = length; n > 0; n -= 4, src += 2) { + *dest++ = *(src + 2); + *dest++ = *(src + 3); + *dest++ = *src++; + *dest++ = *src++; + } + } +} + +static void +SwapNibbles (src, dest, srclen, srcinc, destinc, height) + register unsigned char *src, *dest; + long srclen, srcinc, destinc; + unsigned int height; +{ + register long h, n; + register Const unsigned char *rev = _reverse_nibs; + + srcinc -= srclen; + destinc -= srclen; + for (h = height; --h >= 0; src += srcinc, dest += destinc) + for (n = srclen; --n >= 0; ) + *dest++ = rev[*src++]; +} + +static void +ShiftNibblesLeft (src, dest, srclen, srcinc, destinc, height, nibble_order) + register unsigned char *src, *dest; + long srclen, srcinc, destinc; + unsigned int height; + int nibble_order; +{ + register long h, n; + register unsigned char c1, c2; + + srcinc -= srclen; + destinc -= srclen; + if (nibble_order == MSBFirst) { + for (h = height; --h >= 0; src += srcinc, dest += destinc) + for (n = srclen; --n >= 0; ) { + c1 = *src++; + c2 = *src; + *dest++ = ((c1 & 0x0f) << 4) | ((c2 & (unsigned)0xf0) >> 4); + } + } else { + for (h = height; --h >= 0; src += srcinc, dest += destinc) + for (n = srclen; --n >= 0; ) { + c1 = *src++; + c2 = *src; + *dest++ = ((c2 & 0x0f) << 4) | ((c1 & (unsigned)0xf0) >> 4); + } + } +} + +/*ARGSUSED*/ +static void +SwapBits (src, dest, srclen, srcinc, destinc, height, half_order) + register unsigned char *src, *dest; + long srclen, srcinc, destinc; + unsigned int height; + int half_order; +{ + register long h, n; + register Const unsigned char *rev = _reverse_byte; + + srcinc -= srclen; + destinc -= srclen; + for (h = height; --h >= 0; src += srcinc, dest += destinc) + for (n = srclen; --n >= 0; ) + *dest++ = rev[*src++]; +} + +static void +SwapBitsAndTwoBytes (src, dest, srclen, srcinc, destinc, height, half_order) + register unsigned char *src, *dest; + long srclen, srcinc, destinc; + unsigned int height; +{ + long length = ROUNDUP(srclen, 2); + register long h, n; + register Const unsigned char *rev = _reverse_byte; + + srcinc -= length; + destinc -= length; + for (h = height; --h >= 0; src += srcinc, dest += destinc) { + if ((h == 0) && (srclen != length)) { + length -= 2; + if (half_order == MSBFirst) + *(dest + length) = rev[*(src + length + 1)]; + else + *(dest + length + 1) = rev[*(src + length)]; + } + for (n = length; n > 0; n -= 2, src += 2) { + *dest++ = rev[*(src + 1)]; + *dest++ = rev[*src]; + } + } +} + +static void +SwapBitsAndFourBytes (src, dest, srclen, srcinc, destinc, height, half_order) + register unsigned char *src, *dest; + long srclen, srcinc, destinc; + unsigned int height; + int half_order; +{ + long length = ROUNDUP(srclen, 4); + register long h, n; + register Const unsigned char *rev = _reverse_byte; + + srcinc -= length; + destinc -= length; + for (h = height; --h >= 0; src += srcinc, dest += destinc) { + if ((h == 0) && (srclen != length)) { + length -= 4; + if (half_order == MSBFirst) + *(dest + length) = rev[*(src + length + 3)]; + if (((half_order == LSBFirst) && ((srclen - length) == 3)) || + ((half_order == MSBFirst) && (srclen & 2))) + *(dest + length + 1) = rev[*(src + length + 2)]; + if (((half_order == MSBFirst) && ((srclen - length) == 3)) || + ((half_order == LSBFirst) && (srclen & 2))) + *(dest + length + 2) = rev[*(src + length + 1)]; + if (half_order == LSBFirst) + *(dest + length + 3) = rev[*(src + length)]; + } + for (n = length; n > 0; n -= 4, src += 4) { + *dest++ = rev[*(src + 3)]; + *dest++ = rev[*(src + 2)]; + *dest++ = rev[*(src + 1)]; + *dest++ = rev[*src]; + } + } +} + +static void +SwapBitsAndWords (src, dest, srclen, srcinc, destinc, height, half_order) + register unsigned char *src, *dest; + long srclen, srcinc, destinc; + unsigned int height; + int half_order; +{ + long length = ROUNDUP(srclen, 4); + register long h, n; + register Const unsigned char *rev = _reverse_byte; + + srcinc -= length; + destinc -= length; + for (h = height; --h >= 0; src += srcinc, dest += destinc) { + if ((h == 0) && (srclen != length)) { + length -= 4; + if (half_order == MSBFirst) + *(dest + length + 1) = rev[*(src + length + 3)]; + if (((half_order == LSBFirst) && ((srclen - length) == 3)) || + ((half_order == MSBFirst) && (srclen & 2))) + *(dest + length) = rev[*(src + length + 2)]; + if (((half_order == MSBFirst) && ((srclen - length) == 3)) || + ((half_order == LSBFirst) && (srclen & 2))) + *(dest + length + 3) = rev[*(src + length + 1)]; + if (half_order == LSBFirst) + *(dest + length + 2) = rev[*(src + length)]; + } + for (n = length; n > 0; n -= 4, src += 2) { + *dest++ = rev[*(src + 2)]; + *dest++ = rev[*(src + 3)]; + *dest++ = rev[*src++]; + *dest++ = rev[*src++]; + } + } +} + +/* + +The following table gives the bit ordering within bytes (when accessed +sequentially) for a scanline containing 32 bits, with bits numbered 0 to +31, where bit 0 should be leftmost on the display. For a given byte +labelled A-B, A is for the most significant bit of the byte, and B is +for the least significant bit. + +legend: + 1 scanline-unit = 8 + 2 scanline-unit = 16 + 4 scanline-unit = 32 + M byte-order = MostSignificant + L byte-order = LeastSignificant + m bit-order = MostSignificant + l bit-order = LeastSignificant + + +format ordering + +1Mm 00-07 08-15 16-23 24-31 +2Mm 00-07 08-15 16-23 24-31 +4Mm 00-07 08-15 16-23 24-31 +1Ml 07-00 15-08 23-16 31-24 +2Ml 15-08 07-00 31-24 23-16 +4Ml 31-24 23-16 15-08 07-00 +1Lm 00-07 08-15 16-23 24-31 +2Lm 08-15 00-07 24-31 16-23 +4Lm 24-31 16-23 08-15 00-07 +1Ll 07-00 15-08 23-16 31-24 +2Ll 07-00 15-08 23-16 31-24 +4Ll 07-00 15-08 23-16 31-24 + + +The following table gives the required conversion between any two +formats. It is based strictly on the table above. If you believe one, +you should believe the other. + +legend: + n no changes + s reverse 8-bit units within 16-bit units + l reverse 8-bit units within 32-bit units + w reverse 16-bit units within 32-bit units + R reverse bits within 8-bit units + S s+R + L l+R + W w+R + +*/ + +static void (* RConst (SwapFunction[12][12]))() = { +#define n NoSwap, +#define s SwapTwoBytes, +#define l SwapFourBytes, +#define w SwapWords, +#define R SwapBits, +#define S SwapBitsAndTwoBytes, +#define L SwapBitsAndFourBytes, +#define W SwapBitsAndWords, + +/* 1Mm 2Mm 4Mm 1Ml 2Ml 4Ml 1Lm 2Lm 4Lm 1Ll 2Ll 4Ll */ +/* 1Mm */ { n n n R S L n s l R R R }, +/* 2Mm */ { n n n R S L n s l R R R }, +/* 4Mm */ { n n n R S L n s l R R R }, +/* 1Ml */ { R R R n s l R S L n n n }, +/* 2Ml */ { S S S s n w S R W s s s }, +/* 4Ml */ { L L L l w n L W R l l l }, +/* 1Lm */ { n n n R S L n s l R R R }, +/* 2Lm */ { s s s S R W s n w S S S }, +/* 4Lm */ { l l l L W R l w n L L L }, +/* 1Ll */ { R R R n s l R S L n n n }, +/* 2Ll */ { R R R n s l R S L n n n }, +/* 4Ll */ { R R R n s l R S L n n n } + +#undef n +#undef s +#undef l +#undef w +#undef R +#undef S +#undef L +#undef W + +}; + +/* Of course, the table above is a lie. We also need to factor in the + * order of the source data to cope with swapping half of a unit at the + * end of a scanline, since we are trying to avoid de-ref'ing off the + * end of the source. + * + * Defines whether the first half of a unit has the first half of the data + */ +static int Const HalfOrder[12] = { + LSBFirst, /* 1Mm */ + LSBFirst, /* 2Mm */ + LSBFirst, /* 4Mm */ + LSBFirst, /* 1Ml */ + MSBFirst, /* 2Ml */ + MSBFirst, /* 4Ml */ + LSBFirst, /* 1Lm */ + MSBFirst, /* 2Lm */ + MSBFirst, /* 4Lm */ + LSBFirst, /* 1Ll */ + LSBFirst, /* 2Ll */ + LSBFirst /* 4Ll */ + }; + +/* Finally, for SwapWords cases, the half order depends not just on the source + * but also on the destination scanline unit. Use of this table changes some + * MSBFirsts to LSBFirsts that are "do not care" (because the function will be + * NoSwap or SwapBits) in addition to changing the desired ones. + */ + +static int Const HalfOrderWord[12] = { + MSBFirst, /* 1Mm */ + MSBFirst, /* 2Mm */ + MSBFirst, /* 4Mm */ + MSBFirst, /* 1Ml */ + MSBFirst, /* 2Ml */ + LSBFirst, /* 4Ml */ + MSBFirst, /* 1Lm */ + MSBFirst, /* 2Lm */ + LSBFirst, /* 4Lm */ + MSBFirst, /* 1Ll */ + MSBFirst, /* 2Ll */ + MSBFirst /* 4Ll */ + }; + +/* + * This macro creates a value from 0 to 11 suitable for indexing + * into the table above. + */ +#define ComposeIndex(bitmap_unit, bitmap_bit_order, byte_order) \ + (((bitmap_unit == 32) ? 2 : ((bitmap_unit == 16) ? 1 : 0)) \ + + (((bitmap_bit_order == MSBFirst) ? 0 : 3) \ + + ((byte_order == MSBFirst) ? 0 : 6))) + +/* Cancel a GetReq operation, before doing _XSend or Data */ + +#if (defined(__STDC__) && !defined(UNIXCPP)) || defined(ANSICPP) +#define UnGetReq(name)\ + dpy->bufptr -= SIZEOF(x##name##Req);\ + dpy->request-- +#else +#define UnGetReq(name)\ + dpy->bufptr -= SIZEOF(x/**/name/**/Req);\ + dpy->request-- +#endif + +static void +SendXYImage(dpy, req, image, req_xoffset, req_yoffset) + register Display *dpy; + register xPutImageReq *req; + register XImage *image; + int req_xoffset, req_yoffset; +{ + register int j; + long total_xoffset, bytes_per_src, bytes_per_dest, length; + long bytes_per_line, bytes_per_src_plane, bytes_per_dest_plane; + char *src, *dest, *buf; + char *extra = (char *)NULL; + register void (*swapfunc)(); + int half_order; + + total_xoffset = image->xoffset + req_xoffset; + req->leftPad = total_xoffset & (dpy->bitmap_unit - 1); + total_xoffset = (unsigned)(total_xoffset - req->leftPad) >> 3; + /* The protocol requires left-pad of zero on all ZPixmap, even + * though the 1-bit case is identical to bitmap format. This is a + * bug in the protocol, caused because 1-bit ZPixmap was added late + * in the game. Hairy shifting code compensation isn't worth it, + * just use XYPixmap format instead. + */ + if ((req->leftPad != 0) && (req->format == ZPixmap)) + req->format = XYPixmap; + bytes_per_dest = (unsigned long)ROUNDUP((long)req->width + req->leftPad, + dpy->bitmap_pad) >> 3; + bytes_per_dest_plane = bytes_per_dest * req->height; + length = bytes_per_dest_plane * image->depth; + req->length += (length + 3) >> 2; + + swapfunc = SwapFunction[ComposeIndex(image->bitmap_unit, + image->bitmap_bit_order, + image->byte_order)] + [ComposeIndex(dpy->bitmap_unit, + dpy->bitmap_bit_order, + dpy->byte_order)]; + half_order = HalfOrder[ComposeIndex(image->bitmap_unit, + image->bitmap_bit_order, + image->byte_order)]; + if (half_order == MSBFirst) + half_order = HalfOrderWord[ComposeIndex(dpy->bitmap_unit, + dpy->bitmap_bit_order, + dpy->byte_order)]; + + src = image->data + (image->bytes_per_line * req_yoffset) + total_xoffset; + + /* when total_xoffset > 0, we have to worry about stepping off the + * end of image->data. + */ + if ((swapfunc == NoSwap) && + (image->bytes_per_line == bytes_per_dest) && + (((total_xoffset == 0) && + ((image->depth == 1) || (image->height == req->height))) || + ((image->depth == 1) && + ((req_yoffset + req->height) < (unsigned)image->height)))) { + Data(dpy, src, length); + return; + } + + length = ROUNDUP(length, 4); + if ((dpy->bufptr + length) > dpy->bufmax) { + if ((buf = _XAllocScratch(dpy, (unsigned long) (length))) == NULL) { + UnGetReq(PutImage); + return; + } + } + else + buf = dpy->bufptr; + + bytes_per_src = (req->width + req->leftPad + (unsigned)7) >> 3; + bytes_per_line = image->bytes_per_line; + bytes_per_src_plane = bytes_per_line * image->height; + total_xoffset &= (image->bitmap_unit - 1) >> 3; + + if ((total_xoffset > 0) && + (image->byte_order != image->bitmap_bit_order)) { + char *temp; + long bytes_per_temp_plane, temp_length; + + bytes_per_line = bytes_per_src + total_xoffset; + src -= total_xoffset; + bytes_per_temp_plane = bytes_per_line * req->height; + temp_length = ROUNDUP(bytes_per_temp_plane * image->depth, 4); + if (buf == dpy->bufptr) { + if (! (temp = _XAllocScratch(dpy, (unsigned long) temp_length))) { + UnGetReq(PutImage); + return; + } + } + else + if ((extra = temp = Xmalloc((unsigned) temp_length)) == NULL) { + UnGetReq(PutImage); + return; + } + + swapfunc = SwapFunction[ComposeIndex(image->bitmap_unit, + image->bitmap_bit_order, + image->byte_order)] + [ComposeIndex(image->bitmap_unit, + dpy->byte_order, + dpy->byte_order)]; + for (dest = temp, j = image->depth; + --j >= 0; + src += bytes_per_src_plane, dest += bytes_per_temp_plane) + (*swapfunc)((unsigned char *)src, (unsigned char *)dest, + bytes_per_line, (long)image->bytes_per_line, + bytes_per_line, req->height, half_order); + swapfunc = SwapFunction[ComposeIndex(image->bitmap_unit, + dpy->byte_order, + dpy->byte_order)] + [ComposeIndex(dpy->bitmap_unit, + dpy->bitmap_bit_order, + dpy->byte_order)]; + half_order = HalfOrder[ComposeIndex(image->bitmap_unit, + dpy->byte_order, + dpy->byte_order)]; + src = temp + total_xoffset; + bytes_per_src_plane = bytes_per_temp_plane; + } + + for (dest = buf, j = image->depth; + --j >= 0; + src += bytes_per_src_plane, dest += bytes_per_dest_plane) + (*swapfunc)((unsigned char *)src, (unsigned char *)dest, + bytes_per_src, bytes_per_line, + bytes_per_dest, req->height, half_order); + + if (extra) + Xfree(extra); + + if (buf == dpy->bufptr) + dpy->bufptr += length; + else + _XSend(dpy, buf, length); + } + +static void +SendZImage(dpy, req, image, req_xoffset, req_yoffset, + dest_bits_per_pixel, dest_scanline_pad) + register Display *dpy; + register xPutImageReq *req; + register XImage *image; + int req_xoffset, req_yoffset, dest_bits_per_pixel, dest_scanline_pad; +{ + long bytes_per_src, bytes_per_dest, length; + unsigned char *src, *dest; + unsigned char *shifted_src = NULL; + + req->leftPad = 0; + bytes_per_src = ROUNDUP((long)req->width * image->bits_per_pixel, 8) >> 3; + bytes_per_dest = ROUNDUP((long)req->width * dest_bits_per_pixel, + dest_scanline_pad) >> 3; + length = bytes_per_dest * req->height; + req->length += (length + 3) >> 2; + + src = (unsigned char *)image->data + + (req_yoffset * image->bytes_per_line) + + ((req_xoffset * image->bits_per_pixel) >> 3); + if ((image->bits_per_pixel == 4) && ((unsigned int) req_xoffset & 0x01)) { + if (! (shifted_src = (unsigned char *) + Xmalloc((unsigned) (req->height * image->bytes_per_line)))) { + UnGetReq(PutImage); + return; + } + + ShiftNibblesLeft(src, shifted_src, bytes_per_src, + (long) image->bytes_per_line, + (long) image->bytes_per_line, req->height, + image->byte_order); + src = shifted_src; + } + + /* when req_xoffset > 0, we have to worry about stepping off the + * end of image->data. + */ + if (((image->byte_order == dpy->byte_order) || + (image->bits_per_pixel == 8)) && + ((long)image->bytes_per_line == bytes_per_dest) && + ((req_xoffset == 0) || + ((req_yoffset + req->height) < (unsigned)image->height))) { + Data(dpy, (char *)src, length); + if (shifted_src) + Xfree((char *)shifted_src); + return; + } + + length = ROUNDUP(length, 4); + if ((dpy->bufptr + length) <= dpy->bufmax) + dest = (unsigned char *)dpy->bufptr; + else + if ((dest = (unsigned char *) + _XAllocScratch(dpy, (unsigned long)(length))) == NULL) { + if (shifted_src) Xfree((char *) shifted_src); + UnGetReq(PutImage); + return; + } + + if ((image->byte_order == dpy->byte_order) || + (image->bits_per_pixel == 8)) + NoSwap(src, dest, bytes_per_src, (long)image->bytes_per_line, + bytes_per_dest, req->height, image->byte_order); + else if (image->bits_per_pixel == 32) + SwapFourBytes(src, dest, bytes_per_src, (long)image->bytes_per_line, + bytes_per_dest, req->height, image->byte_order); + else if (image->bits_per_pixel == 24) + SwapThreeBytes(src, dest, bytes_per_src, (long)image->bytes_per_line, + bytes_per_dest, req->height, image->byte_order); + else if (image->bits_per_pixel == 16) + SwapTwoBytes(src, dest, bytes_per_src, (long)image->bytes_per_line, + bytes_per_dest, req->height, image->byte_order); + else + SwapNibbles(src, dest, bytes_per_src, (long)image->bytes_per_line, + bytes_per_dest, req->height); + + if (dest == (unsigned char *)dpy->bufptr) + dpy->bufptr += length; + else + _XSend(dpy, (char *)dest, length); + + if (shifted_src) + Xfree((char *)shifted_src); +} + +static void +PutImageRequest(dpy, d, gc, image, req_xoffset, req_yoffset, x, y, + req_width, req_height, dest_bits_per_pixel, dest_scanline_pad) + register Display *dpy; + Drawable d; + GC gc; + register XImage *image; + int x, y; + unsigned int req_width, req_height; + int req_xoffset, req_yoffset, dest_bits_per_pixel, dest_scanline_pad; +{ + register xPutImageReq *req; + + GetReq(PutImage, req); + req->drawable = d; + req->gc = gc->gid; + req->dstX = x; + req->dstY = y; + req->width = req_width; + req->height = req_height; + req->depth = image->depth; + req->format = image->format; + if ((image->bits_per_pixel == 1) || (image->format != ZPixmap)) + SendXYImage(dpy, req, image, req_xoffset, req_yoffset); + else + SendZImage(dpy, req, image, req_xoffset, req_yoffset, + dest_bits_per_pixel, dest_scanline_pad); +} + +static void +PutSubImage (dpy, d, gc, image, req_xoffset, req_yoffset, x, y, + req_width, req_height, dest_bits_per_pixel, dest_scanline_pad) + register Display *dpy; + Drawable d; + GC gc; + register XImage *image; + int x, y; + unsigned int req_width, req_height; + int req_xoffset, req_yoffset, dest_bits_per_pixel, dest_scanline_pad; + +{ + int left_pad, BytesPerRow, Available; + + if ((req_width == 0) || (req_height == 0)) + return; + + Available = ((65536 < dpy->max_request_size) ? (65536 << 2) + : (dpy->max_request_size << 2)) + - SIZEOF(xPutImageReq); + + if ((image->bits_per_pixel == 1) || (image->format != ZPixmap)) { + left_pad = (image->xoffset + req_xoffset) & (dpy->bitmap_unit - 1); + BytesPerRow = (ROUNDUP((long)req_width + left_pad, + dpy->bitmap_pad) >> 3) * image->depth; + } else { + left_pad = 0; + BytesPerRow = ROUNDUP((long)req_width * dest_bits_per_pixel, + dest_scanline_pad) >> 3; + } + + if ((BytesPerRow * req_height) <= Available) { + PutImageRequest(dpy, d, gc, image, req_xoffset, req_yoffset, x, y, + req_width, req_height, + dest_bits_per_pixel, dest_scanline_pad); + } else if (req_height > 1) { + int SubImageHeight = Available / BytesPerRow; + + if (SubImageHeight == 0) + SubImageHeight = 1; + + PutSubImage(dpy, d, gc, image, req_xoffset, req_yoffset, x, y, + req_width, (unsigned int) SubImageHeight, + dest_bits_per_pixel, dest_scanline_pad); + + PutSubImage(dpy, d, gc, image, req_xoffset, + req_yoffset + SubImageHeight, x, y + SubImageHeight, + req_width, req_height - SubImageHeight, + dest_bits_per_pixel, dest_scanline_pad); + } else { + int SubImageWidth = (((Available << 3) / dest_scanline_pad) + * dest_scanline_pad) - left_pad; + + PutSubImage(dpy, d, gc, image, req_xoffset, req_yoffset, x, y, + (unsigned int) SubImageWidth, 1, + dest_bits_per_pixel, dest_scanline_pad); + + PutSubImage(dpy, d, gc, image, req_xoffset + SubImageWidth, + req_yoffset, x + SubImageWidth, y, + req_width - SubImageWidth, 1, + dest_bits_per_pixel, dest_scanline_pad); + } +} + +XPutImage (dpy, d, gc, image, req_xoffset, req_yoffset, x, y, req_width, + req_height) + register Display *dpy; + Drawable d; + GC gc; + register XImage *image; + int x, y; + unsigned int req_width, req_height; + int req_xoffset, req_yoffset; + +{ + long width = req_width; + long height = req_height; + int dest_bits_per_pixel, dest_scanline_pad; + + if (req_xoffset < 0) { + width += req_xoffset; + req_xoffset = 0; + } + if (req_yoffset < 0) { + height += req_yoffset; + req_yoffset = 0; + } + if ((req_xoffset + width) > image->width) + width = image->width - req_xoffset; + if ((req_yoffset + height) > image->height) + height = image->height - req_yoffset; + if ((width <= 0) || (height <= 0)) + return 0; + + if ((image->bits_per_pixel == 1) || (image->format != ZPixmap)) { + dest_bits_per_pixel = 1; + dest_scanline_pad = dpy->bitmap_pad; + } else { + register int n; + register ScreenFormat *format; + + dest_bits_per_pixel = image->bits_per_pixel; + dest_scanline_pad = image->bitmap_pad; + for (n = dpy->nformats, format = dpy->pixmap_format; --n >= 0; format++) + if (format->depth == image->depth) { + dest_bits_per_pixel = format->bits_per_pixel; + dest_scanline_pad = format->scanline_pad; + } + if (dest_bits_per_pixel != image->bits_per_pixel) { + XImage img; + register long i, j; + extern void _XInitImageFuncPtrs(); + /* XXX slow, but works */ + img.width = width; + img.height = height; + img.xoffset = 0; + img.format = ZPixmap; + img.byte_order = dpy->byte_order; + img.bitmap_unit = dpy->bitmap_unit; + img.bitmap_bit_order = dpy->bitmap_bit_order; + img.bitmap_pad = dest_scanline_pad; + img.depth = image->depth; + img.bits_per_pixel = dest_bits_per_pixel; + img.bytes_per_line = ROUNDUP((dest_bits_per_pixel * width), + dest_scanline_pad) >> 3; + img.data = Xmalloc((unsigned) (img.bytes_per_line * height)); + if (img.data == NULL) + return 0; + _XInitImageFuncPtrs(&img); + for (j = height; --j >= 0; ) + for (i = width; --i >= 0; ) + XPutPixel(&img, i, j, XGetPixel(image, req_xoffset + i, + req_yoffset + j)); + LockDisplay(dpy); + FlushGC(dpy, gc); + PutSubImage(dpy, d, gc, &img, 0, 0, x, y, + (unsigned int) width, (unsigned int) height, + dest_bits_per_pixel, dest_scanline_pad); + UnlockDisplay(dpy); + SyncHandle(); + Xfree(img.data); + return 0; + } + } + + LockDisplay(dpy); + FlushGC(dpy, gc); + + PutSubImage(dpy, d, gc, image, req_xoffset, req_yoffset, x, y, + (unsigned int) width, (unsigned int) height, + dest_bits_per_pixel, dest_scanline_pad); + + UnlockDisplay(dpy); + SyncHandle(); + return 0; +} diff --git a/src/QuBest.c b/src/QuBest.c new file mode 100644 index 00000000..ac857af4 --- /dev/null +++ b/src/QuBest.c @@ -0,0 +1,58 @@ +/* $Xorg: QuBest.c,v 1.4 2001/02/09 02:03:35 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#define NEED_REPLIES +#include "Xlibint.h" + +Status XQueryBestSize(dpy, class, drawable, width, height, ret_width, ret_height) + register Display *dpy; + int class; + Drawable drawable; + unsigned int width, height; + unsigned int *ret_width, *ret_height; +{ + xQueryBestSizeReply rep; + register xQueryBestSizeReq *req; + + LockDisplay(dpy); + GetReq(QueryBestSize, req); + req->class = class; + req->drawable = drawable; + req->width = width; + req->height = height; + if (_XReply (dpy, (xReply *)&rep, 0, xTrue) == 0) { + UnlockDisplay(dpy); + SyncHandle(); + return 0; + } + *ret_width = rep.width; + *ret_height = rep.height; + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} + diff --git a/src/QuColor.c b/src/QuColor.c new file mode 100644 index 00000000..fcd0517f --- /dev/null +++ b/src/QuColor.c @@ -0,0 +1,59 @@ +/* $Xorg: QuColor.c,v 1.4 2001/02/09 02:03:35 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#define NEED_REPLIES +#include "Xlibint.h" + +XQueryColor(dpy, cmap, def) + register Display *dpy; + Colormap cmap; + XColor *def; /* RETURN */ +{ + xrgb color; + xQueryColorsReply rep; + register xQueryColorsReq *req; + unsigned long val = def->pixel; /* needed for macro below */ + + LockDisplay(dpy); + GetReqExtra(QueryColors, 4, req); /* a pixel (CARD32) is 4 bytes */ + req->cmap = cmap; + + OneDataCard32 (dpy, NEXTPTR(req,xQueryColorsReq), val); + + if (_XReply(dpy, (xReply *) &rep, 0, xFalse) != 0) { + + _XRead(dpy, (char *)&color, (long) SIZEOF(xrgb)); + + def->red = color.red; + def->blue = color.blue; + def->green = color.green; + def->flags = DoRed | DoGreen | DoBlue; + } + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} diff --git a/src/QuColors.c b/src/QuColors.c new file mode 100644 index 00000000..0aaed02a --- /dev/null +++ b/src/QuColors.c @@ -0,0 +1,75 @@ +/* $Xorg: QuColors.c,v 1.5 2001/02/09 02:03:35 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#define NEED_REPLIES +#include "Xlibint.h" + +XQueryColors(dpy, cmap, defs, ncolors) + register Display *dpy; + Colormap cmap; + XColor *defs; /* RETURN */ + int ncolors; +{ + register int i; + xrgb *color; + xQueryColorsReply rep; + long nbytes; + register xQueryColorsReq *req; + + LockDisplay(dpy); + GetReq(QueryColors, req); + + req->cmap = cmap; + req->length += ncolors; /* each pixel is a CARD32 */ + + for (i = 0; i < ncolors; i++) + Data32 (dpy, (long *)&defs[i].pixel, 4L); + /* XXX this isn't very efficient */ + + if (_XReply(dpy, (xReply *) &rep, 0, xFalse) != 0) { + if ((color = (xrgb *) + Xmalloc((unsigned) (nbytes = (long) ncolors * SIZEOF(xrgb))))) { + + _XRead(dpy, (char *) color, nbytes); + + for (i = 0; i < ncolors; i++) { + register XColor *def = &defs[i]; + register xrgb *rgb = &color[i]; + def->red = rgb->red; + def->green = rgb->green; + def->blue = rgb->blue; + def->flags = DoRed | DoGreen | DoBlue; + } + Xfree((char *)color); + } + else _XEatData(dpy, (unsigned long) nbytes); + } + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} + diff --git a/src/QuCurShp.c b/src/QuCurShp.c new file mode 100644 index 00000000..3dd42be1 --- /dev/null +++ b/src/QuCurShp.c @@ -0,0 +1,57 @@ +/* $Xorg: QuCurShp.c,v 1.4 2001/02/09 02:03:35 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#define NEED_REPLIES +#include "Xlibint.h" + +Status XQueryBestCursor(dpy, drawable, width, height, ret_width, ret_height) + register Display *dpy; + Drawable drawable; + unsigned int width, height; + unsigned int *ret_width, *ret_height; +{ + xQueryBestSizeReply rep; + register xQueryBestSizeReq *req; + + LockDisplay(dpy); + GetReq(QueryBestSize, req); + req->class = CursorShape; + req->drawable = drawable; + req->width = width; + req->height = height; + if (_XReply (dpy, (xReply *)&rep, 0, xTrue) == 0) { + UnlockDisplay(dpy); + SyncHandle(); + return 0; + } + *ret_width = rep.width; + *ret_height = rep.height; + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} + diff --git a/src/QuExt.c b/src/QuExt.c new file mode 100644 index 00000000..5d49da07 --- /dev/null +++ b/src/QuExt.c @@ -0,0 +1,63 @@ +/* $Xorg: QuExt.c,v 1.4 2001/02/09 02:03:35 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#define NEED_REPLIES +#include "Xlibint.h" + +#if NeedFunctionPrototypes +Bool XQueryExtension( + register Display *dpy, + _Xconst char *name, + int *major_opcode, /* RETURN */ + int *first_event, /* RETURN */ + int *first_error) /* RETURN */ +#else +Bool XQueryExtension(dpy, name, major_opcode, first_event, first_error) + register Display *dpy; + char *name; + int *major_opcode; /* RETURN */ + int *first_event; /* RETURN */ + int *first_error; /* RETURN */ +#endif +{ + xQueryExtensionReply rep; + register xQueryExtensionReq *req; + + LockDisplay(dpy); + GetReq(QueryExtension, req); + req->nbytes = name ? strlen(name) : 0; + req->length += (req->nbytes+(unsigned)3)>>2; + _XSend(dpy, name, (long)req->nbytes); + (void) _XReply (dpy, (xReply *)&rep, 0, xTrue); + *major_opcode = rep.major_opcode; + *first_event = rep.first_event; + *first_error = rep.first_error; + UnlockDisplay(dpy); + SyncHandle(); + return (rep.present); +} + diff --git a/src/QuKeybd.c b/src/QuKeybd.c new file mode 100644 index 00000000..238881ce --- /dev/null +++ b/src/QuKeybd.c @@ -0,0 +1,52 @@ +/* $Xorg: QuKeybd.c,v 1.4 2001/02/09 02:03:35 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#define NEED_REPLIES +#include "Xlibint.h" + +struct kmap { + char map[32]; +}; + +XQueryKeymap(dpy, keys) + register Display *dpy; + char keys[32]; + +{ + xQueryKeymapReply rep; + register xReq *req; + + LockDisplay(dpy); + GetEmptyReq(QueryKeymap, req); + (void) _XReply(dpy, (xReply *)&rep, + (SIZEOF(xQueryKeymapReply) - SIZEOF(xReply)) >> 2, xTrue); + *(struct kmap *) keys = *(struct kmap *)rep.map; /* faster than memcpy */ + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} + diff --git a/src/QuPntr.c b/src/QuPntr.c new file mode 100644 index 00000000..d0b04c1b --- /dev/null +++ b/src/QuPntr.c @@ -0,0 +1,60 @@ +/* $Xorg: QuPntr.c,v 1.4 2001/02/09 02:03:35 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#define NEED_REPLIES +#include "Xlibint.h" + +Bool XQueryPointer(dpy, w, root, child, root_x, root_y, win_x, win_y, mask) + register Display *dpy; + Window w, *root, *child; + int *root_x, *root_y, *win_x, *win_y; + unsigned int *mask; + +{ + xQueryPointerReply rep; + xResourceReq *req; + + LockDisplay(dpy); + GetResReq(QueryPointer, w, req); + if (_XReply (dpy, (xReply *)&rep, 0, xTrue) == 0) { + UnlockDisplay(dpy); + SyncHandle(); + return(False); + } + + *root = rep.root; + *child = rep.child; + *root_x = cvtINT16toInt (rep.rootX); + *root_y = cvtINT16toInt (rep.rootY); + *win_x = cvtINT16toInt (rep.winX); + *win_y = cvtINT16toInt (rep.winY); + *mask = rep.mask; + UnlockDisplay(dpy); + SyncHandle(); + return (rep.sameScreen); +} + diff --git a/src/QuStipShp.c b/src/QuStipShp.c new file mode 100644 index 00000000..81996fc4 --- /dev/null +++ b/src/QuStipShp.c @@ -0,0 +1,57 @@ +/* $Xorg: QuStipShp.c,v 1.4 2001/02/09 02:03:35 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#define NEED_REPLIES +#include "Xlibint.h" + +Status XQueryBestStipple(dpy, drawable, width, height, ret_width, ret_height) + register Display *dpy; + Drawable drawable; + unsigned int width, height; + unsigned int *ret_width, *ret_height; +{ + xQueryBestSizeReply rep; + register xQueryBestSizeReq *req; + + LockDisplay(dpy); + GetReq(QueryBestSize, req); + req->class = StippleShape; + req->drawable = drawable; + req->width = width; + req->height = height; + if (_XReply (dpy, (xReply *)&rep, 0, xTrue) == 0) { + UnlockDisplay(dpy); + SyncHandle(); + return 0; + } + *ret_width = rep.width; + *ret_height = rep.height; + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} + diff --git a/src/QuTextE16.c b/src/QuTextE16.c new file mode 100644 index 00000000..66b3149f --- /dev/null +++ b/src/QuTextE16.c @@ -0,0 +1,91 @@ +/* $Xorg: QuTextE16.c,v 1.5 2001/02/09 02:03:35 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#define NEED_REPLIES +#include "Xlibint.h" + +#if NeedFunctionPrototypes +XQueryTextExtents16 ( + register Display *dpy, + Font fid, + _Xconst XChar2b *string, + register int nchars, + int *dir, + int *font_ascent, + int *font_descent, + register XCharStruct *overall) +#else +XQueryTextExtents16 (dpy, fid, string, nchars, dir, font_ascent, font_descent, + overall) + register Display *dpy; + Font fid; + XChar2b *string; + register int nchars; + int *dir; + int *font_ascent, *font_descent; + register XCharStruct *overall; +#endif +{ + register long i; + register unsigned char *ptr; + char *buf; + xQueryTextExtentsReply rep; + long nbytes; + register xQueryTextExtentsReq *req; + + LockDisplay(dpy); + nbytes = nchars << 1; + GetReq(QueryTextExtents, req); + req->fid = fid; + if ((buf = _XAllocScratch (dpy, (unsigned long) nbytes))) { + req->length += (nbytes + 3)>>2; + req->oddLength = nchars & 1; + for (ptr = (unsigned char *)buf, i = nchars; --i >= 0; string++) { + *ptr++ = string->byte1; + *ptr++ = string->byte2; + } + Data (dpy, buf, nbytes); + } + if (!_XReply (dpy, (xReply *)&rep, 0, xTrue) || !buf) { + UnlockDisplay(dpy); + SyncHandle(); + return 0; + } + *dir = rep.drawDirection; + *font_ascent = cvtINT16toInt (rep.fontAscent); + *font_descent = cvtINT16toInt (rep.fontDescent); + overall->ascent = (short) cvtINT16toShort (rep.overallAscent); + overall->descent = (short) cvtINT16toShort (rep.overallDescent); + /* XXX bogus - we're throwing away information!!! */ + overall->width = (short) cvtINT32toInt (rep.overallWidth); + overall->lbearing = (short) cvtINT32toInt (rep.overallLeft); + overall->rbearing = (short) cvtINT32toInt (rep.overallRight); + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} + diff --git a/src/QuTextExt.c b/src/QuTextExt.c new file mode 100644 index 00000000..bcf8ee17 --- /dev/null +++ b/src/QuTextExt.c @@ -0,0 +1,90 @@ +/* $Xorg: QuTextExt.c,v 1.5 2001/02/09 02:03:35 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#define NEED_REPLIES +#include "Xlibint.h" + +#if NeedFunctionPrototypes +XQueryTextExtents ( + register Display *dpy, + Font fid, + register _Xconst char *string, + register int nchars, + int *dir, + int *font_ascent, + int *font_descent, + register XCharStruct *overall) +#else +XQueryTextExtents (dpy, fid, string, nchars, dir, font_ascent, font_descent, + overall) + register Display *dpy; + Font fid; + register char *string; + register int nchars; + int *dir; + int *font_ascent, *font_descent; + register XCharStruct *overall; +#endif +{ + register int i; + register char *ptr; + char *buf; + xQueryTextExtentsReply rep; + long nbytes; + register xQueryTextExtentsReq *req; + + LockDisplay(dpy); + nbytes = nchars << 1; + GetReq(QueryTextExtents, req); + req->fid = fid; + if ((buf = _XAllocScratch (dpy, (unsigned long) nbytes))) { + req->length += (nbytes + 3)>>2; + req->oddLength = nchars & 1; + for (ptr = buf, i = nchars; --i >= 0;) { + *ptr++ = 0; + *ptr++ = *string++; + } + Data (dpy, buf, nbytes); + } + if (!_XReply (dpy, (xReply *)&rep, 0, xTrue) || !buf) { + UnlockDisplay(dpy); + SyncHandle(); + return 0; + } + *dir = rep.drawDirection; + *font_ascent = cvtINT16toInt (rep.fontAscent); + *font_descent = cvtINT16toInt (rep.fontDescent); + overall->ascent = (short) cvtINT16toShort (rep.overallAscent); + overall->descent = (short) cvtINT16toShort (rep.overallDescent); + /* XXX bogus - we're throwing away information!!! */ + overall->width = (short) cvtINT32toInt (rep.overallWidth); + overall->lbearing = (short) cvtINT32toInt (rep.overallLeft); + overall->rbearing = (short) cvtINT32toInt (rep.overallRight); + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} diff --git a/src/QuTileShp.c b/src/QuTileShp.c new file mode 100644 index 00000000..1c15d17b --- /dev/null +++ b/src/QuTileShp.c @@ -0,0 +1,58 @@ +/* $Xorg: QuTileShp.c,v 1.4 2001/02/09 02:03:35 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#define NEED_REPLIES +#include "Xlibint.h" + +Status XQueryBestTile(dpy, drawable, width, height, ret_width, ret_height) + register Display *dpy; + Drawable drawable; + unsigned int width, height; + unsigned int *ret_width, *ret_height; +{ + xQueryBestSizeReply rep; + register xQueryBestSizeReq *req; + + LockDisplay(dpy); + GetReq(QueryBestSize, req); + req->class = TileShape; + req->drawable = drawable; + req->width = width; + req->height = height; + if (_XReply (dpy, (xReply *)&rep, 0, xTrue) == 0) { + UnlockDisplay(dpy); + SyncHandle(); + return(0); + } + + *ret_width = rep.width; + *ret_height = rep.height; + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} + diff --git a/src/QuTree.c b/src/QuTree.c new file mode 100644 index 00000000..8c6fcc7a --- /dev/null +++ b/src/QuTree.c @@ -0,0 +1,71 @@ +/* $Xorg: QuTree.c,v 1.4 2001/02/09 02:03:35 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#define NEED_REPLIES +#include "Xlibint.h" + +Status XQueryTree (dpy, w, root, parent, children, nchildren) + register Display *dpy; + Window w; + Window *root; /* RETURN */ + Window *parent; /* RETURN */ + Window **children; /* RETURN */ + unsigned int *nchildren; /* RETURN */ +{ + long nbytes; + xQueryTreeReply rep; + register xResourceReq *req; + + LockDisplay(dpy); + GetResReq(QueryTree, w, req); + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return (0); + } + + *children = (Window *) NULL; + if (rep.nChildren != 0) { + nbytes = rep.nChildren * sizeof(Window); + *children = (Window *) Xmalloc((unsigned) nbytes); + nbytes = rep.nChildren << 2; + if (! *children) { + _XEatData(dpy, (unsigned long) nbytes); + UnlockDisplay(dpy); + SyncHandle(); + return (0); + } + _XRead32 (dpy, (char *) *children, nbytes); + } + *parent = rep.parent; + *root = rep.root; + *nchildren = rep.nChildren; + UnlockDisplay(dpy); + SyncHandle(); + return (1); +} + diff --git a/src/Quarks.c b/src/Quarks.c new file mode 100644 index 00000000..98b1b761 --- /dev/null +++ b/src/Quarks.c @@ -0,0 +1,431 @@ +/* $Xorg: Quarks.c,v 1.5 2001/02/09 02:03:35 xorgcvs Exp $ */ + +/*********************************************************** +Copyright 1987, 1988, 1990 by Digital Equipment Corporation, Maynard, + + 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 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. + +******************************************************************/ +/* + +Copyright 1987, 1988, 1990, 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. + +*/ + +#include "Xlibint.h" +#include <X11/Xresource.h> + +/* Not cost effective, at least for vanilla MIT clients */ +/* #define PERMQ */ + +typedef unsigned long Signature; +typedef unsigned long Entry; +#ifdef PERMQ +typedef unsigned char Bits; +#endif + +static XrmQuark nextQuark = 1; /* next available quark number */ +static unsigned long quarkMask = 0; +static Entry zero = 0; +static Entry *quarkTable = &zero; /* crock */ +static unsigned long quarkRehash; +static XrmString **stringTable = NULL; +#ifdef PERMQ +static Bits **permTable = NULL; +#endif +static XrmQuark nextUniq = -1; /* next quark from XrmUniqueQuark */ + +#define QUANTUMSHIFT 8 +#define QUANTUMMASK ((1 << QUANTUMSHIFT) - 1) +#define CHUNKPER 8 +#define CHUNKMASK ((CHUNKPER << QUANTUMSHIFT) - 1) + +#define LARGEQUARK ((Entry)0x80000000L) +#define QUARKSHIFT 18 +#define QUARKMASK ((LARGEQUARK - 1) >> QUARKSHIFT) +#define XSIGMASK ((1L << QUARKSHIFT) - 1) + +#define STRQUANTSIZE (sizeof(XrmString) * (QUANTUMMASK + 1)) +#ifdef PERMQ +#define QUANTSIZE (STRQUANTSIZE + \ + (sizeof(Bits) * ((QUANTUMMASK + 1) >> 3)) +#else +#define QUANTSIZE STRQUANTSIZE +#endif + +#define HASH(sig) ((sig) & quarkMask) +#define REHASHVAL(sig) ((((sig) % quarkRehash) + 2) | 1) +#define REHASH(idx,rehash) ((idx + rehash) & quarkMask) +#define NAME(q) stringTable[(q) >> QUANTUMSHIFT][(q) & QUANTUMMASK] +#ifdef PERMQ +#define BYTEREF(q) permTable[(q) >> QUANTUMSHIFT][((q) & QUANTUMMASK) >> 3] +#define ISPERM(q) (BYTEREF(q) & (1 << ((q) & 7))) +#define SETPERM(q) BYTEREF(q) |= (1 << ((q) & 7)) +#define CLEARPERM(q) BYTEREF(q) &= ~(1 << ((q) & 7)) +#endif + +/* Permanent memory allocation */ + +#define WALIGN sizeof(unsigned long) +#define DALIGN sizeof(double) + +#define NEVERFREETABLESIZE ((8192-12) & ~(DALIGN-1)) +static char *neverFreeTable = NULL; +static int neverFreeTableSize = 0; + +static char *permalloc(length) + register unsigned int length; +{ + char *ret; + + if (neverFreeTableSize < length) { + if (length >= NEVERFREETABLESIZE) + return Xmalloc(length); + if (! (ret = Xmalloc(NEVERFREETABLESIZE))) + return (char *) NULL; + neverFreeTableSize = NEVERFREETABLESIZE; + neverFreeTable = ret; + } + ret = neverFreeTable; + neverFreeTable += length; + neverFreeTableSize -= length; + return(ret); +} + +#ifndef WORD64 +typedef struct {char a; double b;} TestType1; +typedef struct {char a; unsigned long b;} TestType2; +#endif + +#ifdef XTHREADS +static char *_Xpermalloc(); + +char *Xpermalloc(length) + unsigned int length; +{ + char *p; + + _XLockMutex(_Xglobal_lock); + p = _Xpermalloc(length); + _XUnlockMutex(_Xglobal_lock); + return p; +} +#define Xpermalloc _Xpermalloc + +static +#endif /* XTHREADS */ +char *Xpermalloc(length) + unsigned int length; +{ + int i; + + if (neverFreeTableSize && length < NEVERFREETABLESIZE) { +#ifndef WORD64 + if ((sizeof(TestType1) != + (sizeof(TestType2) - sizeof(unsigned long) + sizeof(double))) && + !(length & (DALIGN-1)) && + ((i = (NEVERFREETABLESIZE - neverFreeTableSize) & (DALIGN-1)))) { + neverFreeTableSize -= DALIGN - i; + neverFreeTable += DALIGN - i; + } else +#endif + if ((i = (NEVERFREETABLESIZE - neverFreeTableSize) & (WALIGN-1))) { + neverFreeTableSize -= WALIGN - i; + neverFreeTable += WALIGN - i; + } + } + return permalloc(length); +} + +static Bool +ExpandQuarkTable() +{ + unsigned long oldmask, newmask; + register char c, *s; + register Entry *oldentries, *entries; + register Entry entry; + register int oldidx, newidx, rehash; + Signature sig; + XrmQuark q; + + oldentries = quarkTable; + if ((oldmask = quarkMask)) + newmask = (oldmask << 1) + 1; + else { + if (!stringTable) { + stringTable = (XrmString **)Xmalloc(sizeof(XrmString *) * + CHUNKPER); + if (!stringTable) + return False; + stringTable[0] = (XrmString *)NULL; + } +#ifdef PERMQ + if (!permTable) + permTable = (Bits **)Xmalloc(sizeof(Bits *) * CHUNKPER); + if (!permTable) + return False; +#endif + stringTable[0] = (XrmString *)Xpermalloc(QUANTSIZE); + if (!stringTable[0]) + return False; +#ifdef PERMQ + permTable[0] = (Bits *)((char *)stringTable[0] + STRQUANTSIZE); +#endif + newmask = 0x1ff; + } + entries = (Entry *)Xmalloc(sizeof(Entry) * (newmask + 1)); + if (!entries) + return False; + bzero((char *)entries, sizeof(Entry) * (newmask + 1)); + quarkTable = entries; + quarkMask = newmask; + quarkRehash = quarkMask - 2; + for (oldidx = 0; oldidx <= oldmask; oldidx++) { + if ((entry = oldentries[oldidx])) { + if (entry & LARGEQUARK) + q = entry & (LARGEQUARK-1); + else + q = (entry >> QUARKSHIFT) & QUARKMASK; + for (sig = 0, s = NAME(q); (c = *s++); ) + sig = (sig << 1) + c; + newidx = HASH(sig); + if (entries[newidx]) { + rehash = REHASHVAL(sig); + do { + newidx = REHASH(newidx, rehash); + } while (entries[newidx]); + } + entries[newidx] = entry; + } + } + if (oldmask) + Xfree((char *)oldentries); + return True; +} + +#if NeedFunctionPrototypes +XrmQuark _XrmInternalStringToQuark( + register _Xconst char *name, register int len, register Signature sig, + Bool permstring) +#else +XrmQuark _XrmInternalStringToQuark(name, len, sig, permstring) + register XrmString name; + register int len; + register Signature sig; + Bool permstring; +#endif +{ + register XrmQuark q; + register Entry entry; + register int idx, rehash; + register int i; + register char *s1, *s2; + char *new; + + rehash = 0; + idx = HASH(sig); + _XLockMutex(_Xglobal_lock); + while ((entry = quarkTable[idx])) { + if (entry & LARGEQUARK) + q = entry & (LARGEQUARK-1); + else { + if ((entry - sig) & XSIGMASK) + goto nomatch; + q = (entry >> QUARKSHIFT) & QUARKMASK; + } + for (i = len, s1 = (char *)name, s2 = NAME(q); --i >= 0; ) { + if (*s1++ != *s2++) + goto nomatch; + } + if (*s2) { +nomatch: if (!rehash) + rehash = REHASHVAL(sig); + idx = REHASH(idx, rehash); + continue; + } +#ifdef PERMQ + if (permstring && !ISPERM(q)) { + Xfree(NAME(q)); + NAME(q) = (char *)name; + SETPERM(q); + } +#endif + _XUnlockMutex(_Xglobal_lock); + return q; + } + if (nextUniq == nextQuark) + goto fail; + if ((nextQuark + (nextQuark >> 2)) > quarkMask) { + if (!ExpandQuarkTable()) + goto fail; + _XUnlockMutex(_Xglobal_lock); + return _XrmInternalStringToQuark(name, len, sig, permstring); + } + q = nextQuark; + if (!(q & QUANTUMMASK)) { + if (!(q & CHUNKMASK)) { + if (!(new = Xrealloc((char *)stringTable, + sizeof(XrmString *) * + ((q >> QUANTUMSHIFT) + CHUNKPER)))) + goto fail; + stringTable = (XrmString **)new; +#ifdef PERMQ + if (!(new = Xrealloc((char *)permTable, + sizeof(Bits *) * + ((q >> QUANTUMSHIFT) + CHUNKPER)))) + goto fail; + permTable = (Bits **)new; +#endif + } + new = Xpermalloc(QUANTSIZE); + if (!new) + goto fail; + stringTable[q >> QUANTUMSHIFT] = (XrmString *)new; +#ifdef PERMQ + permTable[q >> QUANTUMSHIFT] = (Bits *)(new + STRQUANTSIZE); +#endif + } + if (!permstring) { + s2 = (char *)name; +#ifdef PERMQ + name = Xmalloc(len+1); +#else + name = permalloc(len+1); +#endif + if (!name) + goto fail; + for (i = len, s1 = (char *)name; --i >= 0; ) + *s1++ = *s2++; + *s1++ = '\0'; +#ifdef PERMQ + CLEARPERM(q); + } + else { + SETPERM(q); +#endif + } + NAME(q) = (char *)name; + if (q <= QUARKMASK) + entry = (q << QUARKSHIFT) | (sig & XSIGMASK); + else + entry = q | LARGEQUARK; + quarkTable[idx] = entry; + nextQuark++; + _XUnlockMutex(_Xglobal_lock); + return q; + fail: + _XUnlockMutex(_Xglobal_lock); + return NULLQUARK; +} + +#if NeedFunctionPrototypes +XrmQuark XrmStringToQuark( + _Xconst char *name) +#else +XrmQuark XrmStringToQuark(name) + XrmString name; +#endif +{ + register char c, *tname; + register Signature sig = 0; + + if (!name) + return (NULLQUARK); + + for (tname = (char *)name; (c = *tname++); ) + sig = (sig << 1) + c; + + return _XrmInternalStringToQuark(name, tname-(char *)name-1, sig, False); +} + +#if NeedFunctionPrototypes +XrmQuark XrmPermStringToQuark( + _Xconst char *name) +#else +XrmQuark XrmPermStringToQuark(name) + XrmString name; +#endif +{ + register char c, *tname; + register Signature sig = 0; + + if (!name) + return (NULLQUARK); + + for (tname = (char *)name; (c = *tname++); ) + sig = (sig << 1) + c; + + return _XrmInternalStringToQuark(name, tname-(char *)name-1, sig, True); +} + +XrmQuark XrmUniqueQuark() +{ + XrmQuark q; + + _XLockMutex(_Xglobal_lock); + if (nextUniq == nextQuark) + q = NULLQUARK; + else + q = nextUniq--; + _XUnlockMutex(_Xglobal_lock); + return q; +} + +XrmString XrmQuarkToString(quark) + register XrmQuark quark; +{ + XrmString s; + + _XLockMutex(_Xglobal_lock); + if (quark <= 0 || quark >= nextQuark) + s = NULLSTRING; + else { +#ifdef PERMQ + /* We have to mark the quark as permanent, since the caller might hold + * onto the string pointer forver. + */ + SETPERM(quark); +#endif + s = NAME(quark); + } + _XUnlockMutex(_Xglobal_lock); + return s; +} diff --git a/src/RaiseWin.c b/src/RaiseWin.c new file mode 100644 index 00000000..7524a5ae --- /dev/null +++ b/src/RaiseWin.c @@ -0,0 +1,46 @@ +/* $Xorg: RaiseWin.c,v 1.4 2001/02/09 02:03:35 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XRaiseWindow (dpy, w) + register Display *dpy; + Window w; +{ + register xConfigureWindowReq *req; + unsigned long val = Above; /* needed for macro below */ + + LockDisplay(dpy); + GetReqExtra(ConfigureWindow, 4, req); + req->window = w; + req->mask = CWStackMode; + OneDataCard32 (dpy, NEXTPTR(req,xConfigureWindowReq), val); + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} + diff --git a/src/RdBitF.c b/src/RdBitF.c new file mode 100644 index 00000000..2b7b3966 --- /dev/null +++ b/src/RdBitF.c @@ -0,0 +1,289 @@ +/* $Xorg: RdBitF.c,v 1.5 2001/02/09 02:03:35 xorgcvs Exp $ */ +/* + +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. + +*/ + +/* + * Code to read bitmaps from disk files. Interprets + * data from X10 and X11 bitmap files and creates + * Pixmap representations of files. Returns Pixmap + * ID and specifics about image. + * + * Modified for speedup by Jim Becker, changed image + * data parsing logic (removed some fscanf()s). + * Aug 5, 1988 + * + * Note that this file and ../Xmu/RdBitF.c look very similar.... Keep them + * that way (but don't use common source code so that people can have one + * without the other). + */ + +#include "Xlibint.h" +#include <X11/Xos.h> +#include "Xutil.h" +#include <stdio.h> +#include <ctype.h> + + +#define MAX_SIZE 255 + +/* shared data for the image read/parse logic */ +static short hexTable[256]; /* conversion value */ +static Bool initialized = False; /* easier to fill in at run time */ + + +/* + * Table index for the hex values. Initialized once, first time. + * Used for translation value or delimiter significance lookup. + */ +static void initHexTable() +{ + /* + * We build the table at run time for several reasons: + * + * 1. portable to non-ASCII machines. + * 2. still reentrant since we set the init flag after setting table. + * 3. easier to extend. + * 4. less prone to bugs. + */ + hexTable['0'] = 0; hexTable['1'] = 1; + hexTable['2'] = 2; hexTable['3'] = 3; + hexTable['4'] = 4; hexTable['5'] = 5; + hexTable['6'] = 6; hexTable['7'] = 7; + hexTable['8'] = 8; hexTable['9'] = 9; + hexTable['A'] = 10; hexTable['B'] = 11; + hexTable['C'] = 12; hexTable['D'] = 13; + hexTable['E'] = 14; hexTable['F'] = 15; + hexTable['a'] = 10; hexTable['b'] = 11; + hexTable['c'] = 12; hexTable['d'] = 13; + hexTable['e'] = 14; hexTable['f'] = 15; + + /* delimiters of significance are flagged w/ negative value */ + hexTable[' '] = -1; hexTable[','] = -1; + hexTable['}'] = -1; hexTable['\n'] = -1; + hexTable['\t'] = -1; + + initialized = True; +} + +/* + * read next hex value in the input stream, return -1 if EOF + */ +static NextInt (fstream) + FILE *fstream; +{ + int ch; + int value = 0; + int gotone = 0; + int done = 0; + + /* loop, accumulate hex value until find delimiter */ + /* skip any initial delimiters found in read stream */ + + while (!done) { + ch = getc(fstream); + if (ch == EOF) { + value = -1; + done++; + } else { + /* trim high bits, check type and accumulate */ + ch &= 0xff; + if (isascii(ch) && isxdigit(ch)) { + value = (value << 4) + hexTable[ch]; + gotone++; + } else if ((hexTable[ch]) < 0 && gotone) + done++; + } + } + return value; +} + +#if NeedFunctionPrototypes +int XReadBitmapFileData ( + _Xconst char *filename, + unsigned int *width, /* RETURNED */ + unsigned int *height, /* RETURNED */ + unsigned char **data, /* RETURNED */ + int *x_hot, /* RETURNED */ + int *y_hot) /* RETURNED */ +#else +int XReadBitmapFileData (filename, width, height, data, x_hot, y_hot) + char *filename; + unsigned int *width, *height; /* RETURNED */ + unsigned char **data; /* RETURNED */ + int *x_hot, *y_hot; /* RETURNED */ +#endif +{ + FILE *fstream; /* handle on file */ + unsigned char *bits = NULL; /* working variable */ + char line[MAX_SIZE]; /* input line from file */ + int size; /* number of bytes of data */ + char name_and_type[MAX_SIZE]; /* an input line */ + char *type; /* for parsing */ + int value; /* from an input line */ + int version10p; /* boolean, old format */ + int padding; /* to handle alignment */ + int bytes_per_line; /* per scanline of data */ + unsigned int ww = 0; /* width */ + unsigned int hh = 0; /* height */ + int hx = -1; /* x hotspot */ + int hy = -1; /* y hotspot */ + + /* first time initialization */ + if (initialized == False) initHexTable(); + + if (!(fstream = fopen(filename, "r"))) + return BitmapOpenFailed; + + /* error cleanup and return macro */ +#define RETURN(code) \ +{ if (bits) Xfree ((char *)bits); fclose (fstream); return code; } + + while (fgets(line, MAX_SIZE, fstream)) { + if (strlen(line) == MAX_SIZE-1) + RETURN (BitmapFileInvalid); + if (sscanf(line,"#define %s %d",name_and_type,&value) == 2) { + if (!(type = strrchr(name_and_type, '_'))) + type = name_and_type; + else + type++; + + if (!strcmp("width", type)) + ww = (unsigned int) value; + if (!strcmp("height", type)) + hh = (unsigned int) value; + if (!strcmp("hot", type)) { + if (type-- == name_and_type || type-- == name_and_type) + continue; + if (!strcmp("x_hot", type)) + hx = value; + if (!strcmp("y_hot", type)) + hy = value; + } + continue; + } + + if (sscanf(line, "static short %s = {", name_and_type) == 1) + version10p = 1; + else if (sscanf(line,"static unsigned char %s = {",name_and_type) == 1) + version10p = 0; + else if (sscanf(line, "static char %s = {", name_and_type) == 1) + version10p = 0; + else + continue; + + if (!(type = strrchr(name_and_type, '_'))) + type = name_and_type; + else + type++; + + if (strcmp("bits[]", type)) + continue; + + if (!ww || !hh) + RETURN (BitmapFileInvalid); + + if ((ww % 16) && ((ww % 16) < 9) && version10p) + padding = 1; + else + padding = 0; + + bytes_per_line = (ww+7)/8 + padding; + + size = bytes_per_line * hh; + bits = (unsigned char *) Xmalloc ((unsigned int) size); + if (!bits) + RETURN (BitmapNoMemory); + + if (version10p) { + unsigned char *ptr; + int bytes; + + for (bytes=0, ptr=bits; bytes<size; (bytes += 2)) { + if ((value = NextInt(fstream)) < 0) + RETURN (BitmapFileInvalid); + *(ptr++) = value; + if (!padding || ((bytes+2) % bytes_per_line)) + *(ptr++) = value >> 8; + } + } else { + unsigned char *ptr; + int bytes; + + for (bytes=0, ptr=bits; bytes<size; bytes++, ptr++) { + if ((value = NextInt(fstream)) < 0) + RETURN (BitmapFileInvalid); + *ptr=value; + } + } + } /* end while */ + + fclose(fstream); + if (!bits) + return (BitmapFileInvalid); + + *data = bits; + *width = ww; + *height = hh; + if (x_hot) *x_hot = hx; + if (y_hot) *y_hot = hy; + + return (BitmapSuccess); +} + +#if NeedFunctionPrototypes +int XReadBitmapFile ( + Display *display, + Drawable d, + _Xconst char *filename, + unsigned int *width, /* RETURNED */ + unsigned int *height, /* RETURNED */ + Pixmap *pixmap, /* RETURNED */ + int *x_hot, /* RETURNED */ + int *y_hot) /* RETURNED */ +#else +int XReadBitmapFile (display, d, filename, width, height, pixmap, x_hot, y_hot) + Display *display; + Drawable d; + char *filename; + unsigned int *width, *height; /* RETURNED */ + Pixmap *pixmap; /* RETURNED */ + int *x_hot, *y_hot; /* RETURNED */ +#endif +{ + unsigned char *data; + int res; + + res = XReadBitmapFileData(filename, width, height, &data, x_hot, y_hot); + if (res != BitmapSuccess) + return res; + *pixmap = XCreateBitmapFromData(display, d, (char *)data, *width, *height); + Xfree((char *)data); + if (*pixmap == None) + return (BitmapNoMemory); + return (BitmapSuccess); +} diff --git a/src/RecolorC.c b/src/RecolorC.c new file mode 100644 index 00000000..06cf31ce --- /dev/null +++ b/src/RecolorC.c @@ -0,0 +1,50 @@ +/* $Xorg: RecolorC.c,v 1.4 2001/02/09 02:03:35 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XRecolorCursor(dpy, cursor, foreground, background) + register Display *dpy; + Cursor cursor; + XColor *foreground, *background; +{ + register xRecolorCursorReq *req; + + LockDisplay(dpy); + GetReq(RecolorCursor, req); + req->cursor = cursor; + req->foreRed = foreground->red; + req->foreGreen = foreground->green; + req->foreBlue = foreground->blue; + req->backRed = background->red; + req->backGreen = background->green; + req->backBlue = background->blue; + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} + diff --git a/src/ReconfWM.c b/src/ReconfWM.c new file mode 100644 index 00000000..c1a6cfb6 --- /dev/null +++ b/src/ReconfWM.c @@ -0,0 +1,139 @@ +/* $Xorg: ReconfWM.c,v 1.4 2001/02/09 02:03:35 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#define NEED_EVENTS +#define NEED_REPLIES +#include "Xlibint.h" + +#define AllMaskBits (CWX|CWY|CWWidth|CWHeight|\ + CWBorderWidth|CWSibling|CWStackMode) + +Status XReconfigureWMWindow (dpy, w, screen, mask, changes) + register Display *dpy; + Window w; + int screen; + unsigned int mask; + XWindowChanges *changes; +{ + XConfigureRequestEvent ev; + Window root = RootWindow (dpy, screen); + _XAsyncHandler async; + _XAsyncErrorState async_state; + + /* + * Only need to go through the trouble if we are actually changing the + * stacking mode. + */ + if (!(mask & CWStackMode)) { + XConfigureWindow (dpy, w, mask, changes); + return True; + } + + + /* + * We need to inline XConfigureWindow and XSync so that everything is done + * while the display is locked. + */ + + LockDisplay(dpy); + + /* + * XConfigureWindow (dpy, w, mask, changes); + */ + { + unsigned long values[7]; + register unsigned long *value = values; + long nvalues; + register xConfigureWindowReq *req; + + GetReq(ConfigureWindow, req); + + async_state.min_sequence_number = dpy->request; + async_state.max_sequence_number = dpy->request; + async_state.error_code = BadMatch; + async_state.major_opcode = X_ConfigureWindow; + async_state.minor_opcode = 0; + async_state.error_count = 0; + async.next = dpy->async_handlers; + async.handler = _XAsyncErrorHandler; + async.data = (XPointer)&async_state; + dpy->async_handlers = &async; + + req->window = w; + mask &= AllMaskBits; + req->mask = mask; + + if (mask & CWX) *value++ = changes->x; + if (mask & CWY) *value++ = changes->y; + if (mask & CWWidth) *value++ = changes->width; + if (mask & CWHeight) *value++ = changes->height; + if (mask & CWBorderWidth) *value++ = changes->border_width; + if (mask & CWSibling) *value++ = changes->sibling; + if (mask & CWStackMode) *value++ = changes->stack_mode; + req->length += (nvalues = value - values); + nvalues <<= 2; /* watch out for macros... */ + Data32 (dpy, (long *) values, nvalues); + } + + /* + * XSync (dpy, 0) + */ + { + xGetInputFocusReply rep; + register xReq *req; + + GetEmptyReq(GetInputFocus, req); + (void) _XReply (dpy, (xReply *)&rep, 0, xTrue); + } + + DeqAsyncHandler(dpy, &async); + UnlockDisplay(dpy); + SyncHandle(); + + + /* + * If the request succeeded, then everything is okay; otherwise, send event + */ + if (!async_state.error_count) return True; + + ev.type = ConfigureRequest; + ev.window = w; + ev.parent = root; + ev.value_mask = (mask & AllMaskBits); + ev.x = changes->x; + ev.y = changes->y; + ev.width = changes->width; + ev.height = changes->height; + ev.border_width = changes->border_width; + ev.above = changes->sibling; + ev.detail = changes->stack_mode; + return (XSendEvent (dpy, root, False, + SubstructureRedirectMask|SubstructureNotifyMask, + (XEvent *)&ev)); +} diff --git a/src/ReconfWin.c b/src/ReconfWin.c new file mode 100644 index 00000000..e1e2fe59 --- /dev/null +++ b/src/ReconfWin.c @@ -0,0 +1,78 @@ +/* $Xorg: ReconfWin.c,v 1.4 2001/02/09 02:03:35 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +#define AllMaskBits (CWX|CWY|CWWidth|CWHeight|\ + CWBorderWidth|CWSibling|CWStackMode) + +XConfigureWindow(dpy, w, mask, changes) + register Display *dpy; + Window w; + unsigned int mask; + XWindowChanges *changes; + { + unsigned long values[7]; + register unsigned long *value = values; + long nvalues; + register xConfigureWindowReq *req; + + LockDisplay(dpy); + GetReq(ConfigureWindow, req); + req->window = w; + mask &= AllMaskBits; + req->mask = mask; + + if (mask & CWX) + *value++ = changes->x; + + if (mask & CWY) + *value++ = changes->y; + + if (mask & CWWidth) + *value++ = changes->width; + + if (mask & CWHeight) + *value++ = changes->height; + + if (mask & CWBorderWidth) + *value++ = changes->border_width; + + if (mask & CWSibling) + *value++ = changes->sibling; + + if (mask & CWStackMode) + *value++ = changes->stack_mode; + + req->length += (nvalues = value - values); + + nvalues <<= 2; /* watch out for macros... */ + Data32 (dpy, (long *) values, nvalues); + UnlockDisplay(dpy); + SyncHandle(); + return 1; + } diff --git a/src/Region.c b/src/Region.c new file mode 100644 index 00000000..c8eeabd6 --- /dev/null +++ b/src/Region.c @@ -0,0 +1,1672 @@ +/* $Xorg: Region.c,v 1.6 2001/02/09 02:03:35 xorgcvs Exp $ */ +/************************************************************************ + +Copyright 1987, 1988, 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, 1988 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 functions in this file implement the Region abstraction, similar to one + * used in the X11 sample server. A Region is simply an area, as the name + * implies, and is implemented as a "y-x-banded" array of rectangles. To + * explain: Each Region is made up of a certain number of rectangles sorted + * by y coordinate first, and then by x coordinate. + * + * Furthermore, the rectangles are banded such that every rectangle with a + * given upper-left y coordinate (y1) will have the same lower-right y + * coordinate (y2) and vice versa. If a rectangle has scanlines in a band, it + * will span the entire vertical distance of the band. This means that some + * areas that could be merged into a taller rectangle will be represented as + * several shorter rectangles to account for shorter rectangles to its left + * or right but within its "vertical scope". + * + * An added constraint on the rectangles is that they must cover as much + * horizontal area as possible. E.g. no two rectangles in a band are allowed + * to touch. + * + * Whenever possible, bands will be merged together to cover a greater vertical + * distance (and thus reduce the number of rectangles). Two bands can be merged + * only if the bottom of one touches the top of the other and they have + * rectangles in the same places (of the same width, of course). This maintains + * the y-x-banding that's so nice to have... + */ + +#include "Xlibint.h" +#include "Xutil.h" +#include "region.h" +#include "poly.h" + +#ifdef DEBUG +#include <stdio.h> +#define assert(expr) {if (!(expr)) fprintf(stderr,\ +"Assertion failed file %s, line %d: expr\n", __FILE__, __LINE__); } +#else +#define assert(expr) +#endif + +typedef void (*voidProcp)(); + +static void miRegionOp(); +/* Create a new empty region */ +Region +XCreateRegion() +{ + Region temp; + + if (! (temp = ( Region )Xmalloc( (unsigned) sizeof( REGION )))) + return (Region) NULL; + if (! (temp->rects = ( BOX * )Xmalloc( (unsigned) sizeof( BOX )))) { + Xfree((char *) temp); + return (Region) NULL; + } + temp->numRects = 0; + temp->extents.x1 = 0; + temp->extents.y1 = 0; + temp->extents.x2 = 0; + temp->extents.y2 = 0; + temp->size = 1; + return( temp ); +} + +XClipBox( r, rect ) + Region r; + XRectangle *rect; +{ + rect->x = r->extents.x1; + rect->y = r->extents.y1; + rect->width = r->extents.x2 - r->extents.x1; + rect->height = r->extents.y2 - r->extents.y1; + return 1; +} + +XUnionRectWithRegion(rect, source, dest) + register XRectangle *rect; + Region source, dest; +{ + REGION region; + + if (!rect->width || !rect->height) + return 0; + region.rects = ®ion.extents; + region.numRects = 1; + region.extents.x1 = rect->x; + region.extents.y1 = rect->y; + region.extents.x2 = rect->x + rect->width; + region.extents.y2 = rect->y + rect->height; + region.size = 1; + + return XUnionRegion(®ion, source, dest); +} + +/*- + *----------------------------------------------------------------------- + * miSetExtents -- + * Reset the extents of a region to what they should be. Called by + * miSubtract and miIntersect b/c they can't figure it out along the + * way or do so easily, as miUnion can. + * + * Results: + * None. + * + * Side Effects: + * The region's 'extents' structure is overwritten. + * + *----------------------------------------------------------------------- + */ +static void +miSetExtents (pReg) + Region pReg; +{ + register BoxPtr pBox, + pBoxEnd, + pExtents; + + if (pReg->numRects == 0) + { + pReg->extents.x1 = 0; + pReg->extents.y1 = 0; + pReg->extents.x2 = 0; + pReg->extents.y2 = 0; + return; + } + + pExtents = &pReg->extents; + pBox = pReg->rects; + pBoxEnd = &pBox[pReg->numRects - 1]; + + /* + * Since pBox is the first rectangle in the region, it must have the + * smallest y1 and since pBoxEnd is the last rectangle in the region, + * it must have the largest y2, because of banding. Initialize x1 and + * x2 from pBox and pBoxEnd, resp., as good things to initialize them + * to... + */ + pExtents->x1 = pBox->x1; + pExtents->y1 = pBox->y1; + pExtents->x2 = pBoxEnd->x2; + pExtents->y2 = pBoxEnd->y2; + + assert(pExtents->y1 < pExtents->y2); + while (pBox <= pBoxEnd) + { + if (pBox->x1 < pExtents->x1) + { + pExtents->x1 = pBox->x1; + } + if (pBox->x2 > pExtents->x2) + { + pExtents->x2 = pBox->x2; + } + pBox++; + } + assert(pExtents->x1 < pExtents->x2); +} + +XSetRegion( dpy, gc, r ) + Display *dpy; + GC gc; + register Region r; +{ + register int i; + register XRectangle *xr, *pr; + register BOX *pb; + unsigned long total; + extern void _XSetClipRectangles(); + + LockDisplay (dpy); + total = r->numRects * sizeof (XRectangle); + if ((xr = (XRectangle *) _XAllocTemp(dpy, total))) { + for (pr = xr, pb = r->rects, i = r->numRects; --i >= 0; pr++, pb++) { + pr->x = pb->x1; + pr->y = pb->y1; + pr->width = pb->x2 - pb->x1; + pr->height = pb->y2 - pb->y1; + } + } + if (xr || !r->numRects) + _XSetClipRectangles(dpy, gc, 0, 0, xr, r->numRects, YXBanded); + if (xr) + _XFreeTemp(dpy, (char *)xr, total); + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} + +XDestroyRegion( r ) + Region r; +{ + Xfree( (char *) r->rects ); + Xfree( (char *) r ); + return 1; +} + + +/* TranslateRegion(pRegion, x, y) + translates in place + added by raymond +*/ + +XOffsetRegion(pRegion, x, y) + register Region pRegion; + register int x; + register int y; +{ + register int nbox; + register BOX *pbox; + + pbox = pRegion->rects; + nbox = pRegion->numRects; + + while(nbox--) + { + pbox->x1 += x; + pbox->x2 += x; + pbox->y1 += y; + pbox->y2 += y; + pbox++; + } + pRegion->extents.x1 += x; + pRegion->extents.x2 += x; + pRegion->extents.y1 += y; + pRegion->extents.y2 += y; + return 1; +} + +/* + Utility procedure Compress: + Replace r by the region r', where + p in r' iff (Quantifer m <= dx) (p + m in r), and + Quantifier is Exists if grow is TRUE, For all if grow is FALSE, and + (x,y) + m = (x+m,y) if xdir is TRUE; (x,y+m) if xdir is FALSE. + + Thus, if xdir is TRUE and grow is FALSE, r is replaced by the region + of all points p such that p and the next dx points on the same + horizontal scan line are all in r. We do this using by noting + that p is the head of a run of length 2^i + k iff p is the head + of a run of length 2^i and p+2^i is the head of a run of length + k. Thus, the loop invariant: s contains the region corresponding + to the runs of length shift. r contains the region corresponding + to the runs of length 1 + dxo & (shift-1), where dxo is the original + value of dx. dx = dxo & ~(shift-1). As parameters, s and t are + scratch regions, so that we don't have to allocate them on every + call. +*/ + +#define ZOpRegion(a,b,c) if (grow) XUnionRegion(a,b,c); \ + else XIntersectRegion(a,b,c) +#define ZShiftRegion(a,b) if (xdir) XOffsetRegion(a,b,0); \ + else XOffsetRegion(a,0,b) +#define ZCopyRegion(a,b) XUnionRegion(a,a,b) + +static void +Compress(r, s, t, dx, xdir, grow) + Region r, s, t; + register unsigned dx; + register int xdir, grow; +{ + register unsigned shift = 1; + + ZCopyRegion(r, s); + while (dx) { + if (dx & shift) { + ZShiftRegion(r, -(int)shift); + ZOpRegion(r, s, r); + dx -= shift; + if (!dx) break; + } + ZCopyRegion(s, t); + ZShiftRegion(s, -(int)shift); + ZOpRegion(s, t, s); + shift <<= 1; + } +} + +#undef ZOpRegion +#undef ZShiftRegion +#undef ZCopyRegion + +XShrinkRegion(r, dx, dy) + Region r; + int dx, dy; +{ + Region s, t; + int grow; + + if (!dx && !dy) return 0; + if ((! (s = XCreateRegion())) || (! (t = XCreateRegion()))) return 0; + if ((grow = (dx < 0))) dx = -dx; + if (dx) Compress(r, s, t, (unsigned) 2*dx, TRUE, grow); + if ((grow = (dy < 0))) dy = -dy; + if (dy) Compress(r, s, t, (unsigned) 2*dy, FALSE, grow); + XOffsetRegion(r, dx, dy); + XDestroyRegion(s); + XDestroyRegion(t); + return 0; +} + +#ifdef notdef +/*********************************************************** + * Bop down the array of rects until we have passed + * scanline y. numRects is the size of the array. + ***********************************************************/ + +static BOX +*IndexRects(rects, numRects, y) + register BOX *rects; + register int numRects; + register int y; +{ + while ((numRects--) && (rects->y2 <= y)) + rects++; + return(rects); +} +#endif + +/*====================================================================== + * Region Intersection + *====================================================================*/ +/*- + *----------------------------------------------------------------------- + * miIntersectO -- + * Handle an overlapping band for miIntersect. + * + * Results: + * None. + * + * Side Effects: + * Rectangles may be added to the region. + * + *----------------------------------------------------------------------- + */ +/* static void*/ +static +miIntersectO (pReg, r1, r1End, r2, r2End, y1, y2) + register Region pReg; + register BoxPtr r1; + BoxPtr r1End; + register BoxPtr r2; + BoxPtr r2End; + short y1; + short y2; +{ + register short x1; + register short x2; + register BoxPtr pNextRect; + + pNextRect = &pReg->rects[pReg->numRects]; + + while ((r1 != r1End) && (r2 != r2End)) + { + x1 = max(r1->x1,r2->x1); + x2 = min(r1->x2,r2->x2); + + /* + * If there's any overlap between the two rectangles, add that + * overlap to the new region. + * There's no need to check for subsumption because the only way + * such a need could arise is if some region has two rectangles + * right next to each other. Since that should never happen... + */ + if (x1 < x2) + { + assert(y1<y2); + + MEMCHECK(pReg, pNextRect, pReg->rects); + pNextRect->x1 = x1; + pNextRect->y1 = y1; + pNextRect->x2 = x2; + pNextRect->y2 = y2; + pReg->numRects += 1; + pNextRect++; + assert(pReg->numRects <= pReg->size); + } + + /* + * Need to advance the pointers. Shift the one that extends + * to the right the least, since the other still has a chance to + * overlap with that region's next rectangle, if you see what I mean. + */ + if (r1->x2 < r2->x2) + { + r1++; + } + else if (r2->x2 < r1->x2) + { + r2++; + } + else + { + r1++; + r2++; + } + } + return 0; /* lint */ +} + +XIntersectRegion(reg1, reg2, newReg) + Region reg1; + Region reg2; /* source regions */ + register Region newReg; /* destination Region */ +{ + /* check for trivial reject */ + if ( (!(reg1->numRects)) || (!(reg2->numRects)) || + (!EXTENTCHECK(®1->extents, ®2->extents))) + newReg->numRects = 0; + else + miRegionOp (newReg, reg1, reg2, + (voidProcp) miIntersectO, (voidProcp) NULL, (voidProcp) NULL); + + /* + * Can't alter newReg's extents before we call miRegionOp because + * it might be one of the source regions and miRegionOp depends + * on the extents of those regions being the same. Besides, this + * way there's no checking against rectangles that will be nuked + * due to coalescing, so we have to examine fewer rectangles. + */ + miSetExtents(newReg); + return 1; +} + +static void +miRegionCopy(dstrgn, rgn) + register Region dstrgn; + register Region rgn; + +{ + if (dstrgn != rgn) /* don't want to copy to itself */ + { + if (dstrgn->size < rgn->numRects) + { + if (dstrgn->rects) + { + BOX *prevRects = dstrgn->rects; + + if (! (dstrgn->rects = (BOX *) + Xrealloc((char *) dstrgn->rects, + (unsigned) rgn->numRects * (sizeof(BOX))))) { + Xfree(prevRects); + return; + } + } + dstrgn->size = rgn->numRects; + } + dstrgn->numRects = rgn->numRects; + dstrgn->extents.x1 = rgn->extents.x1; + dstrgn->extents.y1 = rgn->extents.y1; + dstrgn->extents.x2 = rgn->extents.x2; + dstrgn->extents.y2 = rgn->extents.y2; + + memcpy((char *) dstrgn->rects, (char *) rgn->rects, + (int) (rgn->numRects * sizeof(BOX))); + } +} + +#ifdef notdef + +/* + * combinRegs(newReg, reg1, reg2) + * if one region is above or below the other. +*/ + +static void +combineRegs(newReg, reg1, reg2) + register Region newReg; + Region reg1; + Region reg2; +{ + register Region tempReg; + register BOX *rects; + register BOX *rects1; + register BOX *rects2; + register int total; + + rects1 = reg1->rects; + rects2 = reg2->rects; + + total = reg1->numRects + reg2->numRects; + if (! (tempReg = XCreateRegion())) + return; + tempReg->size = total; + /* region 1 is below region 2 */ + if (reg1->extents.y1 > reg2->extents.y1) + { + miRegionCopy(tempReg, reg2); + rects = &tempReg->rects[tempReg->numRects]; + total -= tempReg->numRects; + while (total--) + *rects++ = *rects1++; + } + else + { + miRegionCopy(tempReg, reg1); + rects = &tempReg->rects[tempReg->numRects]; + total -= tempReg->numRects; + while (total--) + *rects++ = *rects2++; + } + tempReg->extents = reg1->extents; + tempReg->numRects = reg1->numRects + reg2->numRects; + EXTENTS(®2->extents, tempReg); + miRegionCopy(newReg, tempReg); + Xfree((char *)tempReg); +} + +/* + * QuickCheck checks to see if it does not have to go through all the + * the ugly code for the region call. It returns 1 if it did all + * the work for Union, otherwise 0 - still work to be done. +*/ + +static int +QuickCheck(newReg, reg1, reg2) + Region newReg, reg1, reg2; +{ + + /* if unioning with itself or no rects to union with */ + if ( (reg1 == reg2) || (!(reg1->numRects)) ) + { + miRegionCopy(newReg, reg2); + return TRUE; + } + + /* if nothing to union */ + if (!(reg2->numRects)) + { + miRegionCopy(newReg, reg1); + return TRUE; + } + + /* could put an extent check to see if add above or below */ + + if ((reg1->extents.y1 >= reg2->extents.y2) || + (reg2->extents.y1 >= reg1->extents.y2) ) + { + combineRegs(newReg, reg1, reg2); + return TRUE; + } + return FALSE; +} + +/* TopRects(rects, reg1, reg2) + * N.B. We now assume that reg1 and reg2 intersect. Therefore we are + * NOT checking in the two while loops for stepping off the end of the + * region. + */ + +static int +TopRects(newReg, rects, reg1, reg2, FirstRect) + register Region newReg; + register BOX *rects; + register Region reg1; + register Region reg2; + BOX *FirstRect; +{ + register BOX *tempRects; + + /* need to add some rects from region 1 */ + if (reg1->extents.y1 < reg2->extents.y1) + { + tempRects = reg1->rects; + while(tempRects->y1 < reg2->extents.y1) + { + MEMCHECK(newReg, rects, FirstRect); + ADDRECTNOX(newReg,rects, tempRects->x1, tempRects->y1, + tempRects->x2, MIN(tempRects->y2, reg2->extents.y1)); + tempRects++; + } + } + /* need to add some rects from region 2 */ + if (reg2->extents.y1 < reg1->extents.y1) + { + tempRects = reg2->rects; + while (tempRects->y1 < reg1->extents.y1) + { + MEMCHECK(newReg, rects, FirstRect); + ADDRECTNOX(newReg, rects, tempRects->x1,tempRects->y1, + tempRects->x2, MIN(tempRects->y2, reg1->extents.y1)); + tempRects++; + } + } + return 1; +} +#endif + +/*====================================================================== + * Generic Region Operator + *====================================================================*/ + +/*- + *----------------------------------------------------------------------- + * miCoalesce -- + * Attempt to merge the boxes in the current band with those in the + * previous one. Used only by miRegionOp. + * + * Results: + * The new index for the previous band. + * + * Side Effects: + * If coalescing takes place: + * - rectangles in the previous band will have their y2 fields + * altered. + * - pReg->numRects will be decreased. + * + *----------------------------------------------------------------------- + */ +/* static int*/ +static +miCoalesce (pReg, prevStart, curStart) + register Region pReg; /* Region to coalesce */ + int prevStart; /* Index of start of previous band */ + int curStart; /* Index of start of current band */ +{ + register BoxPtr pPrevBox; /* Current box in previous band */ + register BoxPtr pCurBox; /* Current box in current band */ + register BoxPtr pRegEnd; /* End of region */ + int curNumRects; /* Number of rectangles in current + * band */ + int prevNumRects; /* Number of rectangles in previous + * band */ + int bandY1; /* Y1 coordinate for current band */ + + pRegEnd = &pReg->rects[pReg->numRects]; + + pPrevBox = &pReg->rects[prevStart]; + prevNumRects = curStart - prevStart; + + /* + * Figure out how many rectangles are in the current band. Have to do + * this because multiple bands could have been added in miRegionOp + * at the end when one region has been exhausted. + */ + pCurBox = &pReg->rects[curStart]; + bandY1 = pCurBox->y1; + for (curNumRects = 0; + (pCurBox != pRegEnd) && (pCurBox->y1 == bandY1); + curNumRects++) + { + pCurBox++; + } + + if (pCurBox != pRegEnd) + { + /* + * If more than one band was added, we have to find the start + * of the last band added so the next coalescing job can start + * at the right place... (given when multiple bands are added, + * this may be pointless -- see above). + */ + pRegEnd--; + while (pRegEnd[-1].y1 == pRegEnd->y1) + { + pRegEnd--; + } + curStart = pRegEnd - pReg->rects; + pRegEnd = pReg->rects + pReg->numRects; + } + + if ((curNumRects == prevNumRects) && (curNumRects != 0)) { + pCurBox -= curNumRects; + /* + * The bands may only be coalesced if the bottom of the previous + * matches the top scanline of the current. + */ + if (pPrevBox->y2 == pCurBox->y1) + { + /* + * Make sure the bands have boxes in the same places. This + * assumes that boxes have been added in such a way that they + * cover the most area possible. I.e. two boxes in a band must + * have some horizontal space between them. + */ + do + { + if ((pPrevBox->x1 != pCurBox->x1) || + (pPrevBox->x2 != pCurBox->x2)) + { + /* + * The bands don't line up so they can't be coalesced. + */ + return (curStart); + } + pPrevBox++; + pCurBox++; + prevNumRects -= 1; + } while (prevNumRects != 0); + + pReg->numRects -= curNumRects; + pCurBox -= curNumRects; + pPrevBox -= curNumRects; + + /* + * The bands may be merged, so set the bottom y of each box + * in the previous band to that of the corresponding box in + * the current band. + */ + do + { + pPrevBox->y2 = pCurBox->y2; + pPrevBox++; + pCurBox++; + curNumRects -= 1; + } while (curNumRects != 0); + + /* + * If only one band was added to the region, we have to backup + * curStart to the start of the previous band. + * + * If more than one band was added to the region, copy the + * other bands down. The assumption here is that the other bands + * came from the same region as the current one and no further + * coalescing can be done on them since it's all been done + * already... curStart is already in the right place. + */ + if (pCurBox == pRegEnd) + { + curStart = prevStart; + } + else + { + do + { + *pPrevBox++ = *pCurBox++; + } while (pCurBox != pRegEnd); + } + + } + } + return (curStart); +} + +/*- + *----------------------------------------------------------------------- + * miRegionOp -- + * Apply an operation to two regions. Called by miUnion, miInverse, + * miSubtract, miIntersect... + * + * Results: + * None. + * + * Side Effects: + * The new region is overwritten. + * + * Notes: + * The idea behind this function is to view the two regions as sets. + * Together they cover a rectangle of area that this function divides + * into horizontal bands where points are covered only by one region + * or by both. For the first case, the nonOverlapFunc is called with + * each the band and the band's upper and lower extents. For the + * second, the overlapFunc is called to process the entire band. It + * is responsible for clipping the rectangles in the band, though + * this function provides the boundaries. + * At the end of each band, the new region is coalesced, if possible, + * to reduce the number of rectangles in the region. + * + *----------------------------------------------------------------------- + */ +/* static void*/ +static void +miRegionOp(newReg, reg1, reg2, overlapFunc, nonOverlap1Func, nonOverlap2Func) + register Region newReg; /* Place to store result */ + Region reg1; /* First region in operation */ + Region reg2; /* 2d region in operation */ + void (*overlapFunc)(); /* Function to call for over- + * lapping bands */ + void (*nonOverlap1Func)(); /* Function to call for non- + * overlapping bands in region + * 1 */ + void (*nonOverlap2Func)(); /* Function to call for non- + * overlapping bands in region + * 2 */ +{ + register BoxPtr r1; /* Pointer into first region */ + register BoxPtr r2; /* Pointer into 2d region */ + BoxPtr r1End; /* End of 1st region */ + BoxPtr r2End; /* End of 2d region */ + register short ybot; /* Bottom of intersection */ + register short ytop; /* Top of intersection */ + BoxPtr oldRects; /* Old rects for newReg */ + int prevBand; /* Index of start of + * previous band in newReg */ + int curBand; /* Index of start of current + * band in newReg */ + register BoxPtr r1BandEnd; /* End of current band in r1 */ + register BoxPtr r2BandEnd; /* End of current band in r2 */ + short top; /* Top of non-overlapping + * band */ + short bot; /* Bottom of non-overlapping + * band */ + + /* + * Initialization: + * set r1, r2, r1End and r2End appropriately, preserve the important + * parts of the destination region until the end in case it's one of + * the two source regions, then mark the "new" region empty, allocating + * another array of rectangles for it to use. + */ + r1 = reg1->rects; + r2 = reg2->rects; + r1End = r1 + reg1->numRects; + r2End = r2 + reg2->numRects; + + oldRects = newReg->rects; + + EMPTY_REGION(newReg); + + /* + * Allocate a reasonable number of rectangles for the new region. The idea + * is to allocate enough so the individual functions don't need to + * reallocate and copy the array, which is time consuming, yet we don't + * have to worry about using too much memory. I hope to be able to + * nuke the Xrealloc() at the end of this function eventually. + */ + newReg->size = max(reg1->numRects,reg2->numRects) * 2; + + if (! (newReg->rects = (BoxPtr) + Xmalloc ((unsigned) (sizeof(BoxRec) * newReg->size)))) { + newReg->size = 0; + return; + } + + /* + * Initialize ybot and ytop. + * In the upcoming loop, ybot and ytop serve different functions depending + * on whether the band being handled is an overlapping or non-overlapping + * band. + * In the case of a non-overlapping band (only one of the regions + * has points in the band), ybot is the bottom of the most recent + * intersection and thus clips the top of the rectangles in that band. + * ytop is the top of the next intersection between the two regions and + * serves to clip the bottom of the rectangles in the current band. + * For an overlapping band (where the two regions intersect), ytop clips + * the top of the rectangles of both regions and ybot clips the bottoms. + */ + if (reg1->extents.y1 < reg2->extents.y1) + ybot = reg1->extents.y1; + else + ybot = reg2->extents.y1; + + /* + * prevBand serves to mark the start of the previous band so rectangles + * can be coalesced into larger rectangles. qv. miCoalesce, above. + * In the beginning, there is no previous band, so prevBand == curBand + * (curBand is set later on, of course, but the first band will always + * start at index 0). prevBand and curBand must be indices because of + * the possible expansion, and resultant moving, of the new region's + * array of rectangles. + */ + prevBand = 0; + + do + { + curBand = newReg->numRects; + + /* + * This algorithm proceeds one source-band (as opposed to a + * destination band, which is determined by where the two regions + * intersect) at a time. r1BandEnd and r2BandEnd serve to mark the + * rectangle after the last one in the current band for their + * respective regions. + */ + r1BandEnd = r1; + while ((r1BandEnd != r1End) && (r1BandEnd->y1 == r1->y1)) + { + r1BandEnd++; + } + + r2BandEnd = r2; + while ((r2BandEnd != r2End) && (r2BandEnd->y1 == r2->y1)) + { + r2BandEnd++; + } + + /* + * First handle the band that doesn't intersect, if any. + * + * Note that attention is restricted to one band in the + * non-intersecting region at once, so if a region has n + * bands between the current position and the next place it overlaps + * the other, this entire loop will be passed through n times. + */ + if (r1->y1 < r2->y1) + { + top = max(r1->y1,ybot); + bot = min(r1->y2,r2->y1); + + if ((top != bot) && (nonOverlap1Func != (void (*)())NULL)) + { + (* nonOverlap1Func) (newReg, r1, r1BandEnd, top, bot); + } + + ytop = r2->y1; + } + else if (r2->y1 < r1->y1) + { + top = max(r2->y1,ybot); + bot = min(r2->y2,r1->y1); + + if ((top != bot) && (nonOverlap2Func != (void (*)())NULL)) + { + (* nonOverlap2Func) (newReg, r2, r2BandEnd, top, bot); + } + + ytop = r1->y1; + } + else + { + ytop = r1->y1; + } + + /* + * If any rectangles got added to the region, try and coalesce them + * with rectangles from the previous band. Note we could just do + * this test in miCoalesce, but some machines incur a not + * inconsiderable cost for function calls, so... + */ + if (newReg->numRects != curBand) + { + prevBand = miCoalesce (newReg, prevBand, curBand); + } + + /* + * Now see if we've hit an intersecting band. The two bands only + * intersect if ybot > ytop + */ + ybot = min(r1->y2, r2->y2); + curBand = newReg->numRects; + if (ybot > ytop) + { + (* overlapFunc) (newReg, r1, r1BandEnd, r2, r2BandEnd, ytop, ybot); + + } + + if (newReg->numRects != curBand) + { + prevBand = miCoalesce (newReg, prevBand, curBand); + } + + /* + * If we've finished with a band (y2 == ybot) we skip forward + * in the region to the next band. + */ + if (r1->y2 == ybot) + { + r1 = r1BandEnd; + } + if (r2->y2 == ybot) + { + r2 = r2BandEnd; + } + } while ((r1 != r1End) && (r2 != r2End)); + + /* + * Deal with whichever region still has rectangles left. + */ + curBand = newReg->numRects; + if (r1 != r1End) + { + if (nonOverlap1Func != (void (*)())NULL) + { + do + { + r1BandEnd = r1; + while ((r1BandEnd < r1End) && (r1BandEnd->y1 == r1->y1)) + { + r1BandEnd++; + } + (* nonOverlap1Func) (newReg, r1, r1BandEnd, + max(r1->y1,ybot), r1->y2); + r1 = r1BandEnd; + } while (r1 != r1End); + } + } + else if ((r2 != r2End) && (nonOverlap2Func != (void (*)())NULL)) + { + do + { + r2BandEnd = r2; + while ((r2BandEnd < r2End) && (r2BandEnd->y1 == r2->y1)) + { + r2BandEnd++; + } + (* nonOverlap2Func) (newReg, r2, r2BandEnd, + max(r2->y1,ybot), r2->y2); + r2 = r2BandEnd; + } while (r2 != r2End); + } + + if (newReg->numRects != curBand) + { + (void) miCoalesce (newReg, prevBand, curBand); + } + + /* + * A bit of cleanup. To keep regions from growing without bound, + * we shrink the array of rectangles to match the new number of + * rectangles in the region. This never goes to 0, however... + * + * Only do this stuff if the number of rectangles allocated is more than + * twice the number of rectangles in the region (a simple optimization...). + */ + if (newReg->numRects < (newReg->size >> 1)) + { + if (REGION_NOT_EMPTY(newReg)) + { + BoxPtr prev_rects = newReg->rects; + newReg->size = newReg->numRects; + newReg->rects = (BoxPtr) Xrealloc ((char *) newReg->rects, + (unsigned) (sizeof(BoxRec) * newReg->size)); + if (! newReg->rects) + newReg->rects = prev_rects; + } + else + { + /* + * No point in doing the extra work involved in an Xrealloc if + * the region is empty + */ + newReg->size = 1; + Xfree((char *) newReg->rects); + newReg->rects = (BoxPtr) Xmalloc(sizeof(BoxRec)); + } + } + Xfree ((char *) oldRects); + return; +} + + +/*====================================================================== + * Region Union + *====================================================================*/ + +/*- + *----------------------------------------------------------------------- + * miUnionNonO -- + * Handle a non-overlapping band for the union operation. Just + * Adds the rectangles into the region. Doesn't have to check for + * subsumption or anything. + * + * Results: + * None. + * + * Side Effects: + * pReg->numRects is incremented and the final rectangles overwritten + * with the rectangles we're passed. + * + *----------------------------------------------------------------------- + */ +/* static void*/ +static +miUnionNonO (pReg, r, rEnd, y1, y2) + register Region pReg; + register BoxPtr r; + BoxPtr rEnd; + register short y1; + register short y2; +{ + register BoxPtr pNextRect; + + pNextRect = &pReg->rects[pReg->numRects]; + + assert(y1 < y2); + + while (r != rEnd) + { + assert(r->x1 < r->x2); + MEMCHECK(pReg, pNextRect, pReg->rects); + pNextRect->x1 = r->x1; + pNextRect->y1 = y1; + pNextRect->x2 = r->x2; + pNextRect->y2 = y2; + pReg->numRects += 1; + pNextRect++; + + assert(pReg->numRects<=pReg->size); + r++; + } + return 0; /* lint */ +} + + +/*- + *----------------------------------------------------------------------- + * miUnionO -- + * Handle an overlapping band for the union operation. Picks the + * left-most rectangle each time and merges it into the region. + * + * Results: + * None. + * + * Side Effects: + * Rectangles are overwritten in pReg->rects and pReg->numRects will + * be changed. + * + *----------------------------------------------------------------------- + */ + +/* static void*/ +static +miUnionO (pReg, r1, r1End, r2, r2End, y1, y2) + register Region pReg; + register BoxPtr r1; + BoxPtr r1End; + register BoxPtr r2; + BoxPtr r2End; + register short y1; + register short y2; +{ + register BoxPtr pNextRect; + + pNextRect = &pReg->rects[pReg->numRects]; + +#define MERGERECT(r) \ + if ((pReg->numRects != 0) && \ + (pNextRect[-1].y1 == y1) && \ + (pNextRect[-1].y2 == y2) && \ + (pNextRect[-1].x2 >= r->x1)) \ + { \ + if (pNextRect[-1].x2 < r->x2) \ + { \ + pNextRect[-1].x2 = r->x2; \ + assert(pNextRect[-1].x1<pNextRect[-1].x2); \ + } \ + } \ + else \ + { \ + MEMCHECK(pReg, pNextRect, pReg->rects); \ + pNextRect->y1 = y1; \ + pNextRect->y2 = y2; \ + pNextRect->x1 = r->x1; \ + pNextRect->x2 = r->x2; \ + pReg->numRects += 1; \ + pNextRect += 1; \ + } \ + assert(pReg->numRects<=pReg->size);\ + r++; + + assert (y1<y2); + while ((r1 != r1End) && (r2 != r2End)) + { + if (r1->x1 < r2->x1) + { + MERGERECT(r1); + } + else + { + MERGERECT(r2); + } + } + + if (r1 != r1End) + { + do + { + MERGERECT(r1); + } while (r1 != r1End); + } + else while (r2 != r2End) + { + MERGERECT(r2); + } + return 0; /* lint */ +} + +XUnionRegion(reg1, reg2, newReg) + Region reg1; + Region reg2; /* source regions */ + Region newReg; /* destination Region */ +{ + /* checks all the simple cases */ + + /* + * Region 1 and 2 are the same or region 1 is empty + */ + if ( (reg1 == reg2) || (!(reg1->numRects)) ) + { + if (newReg != reg2) + miRegionCopy(newReg, reg2); + return 1; + } + + /* + * if nothing to union (region 2 empty) + */ + if (!(reg2->numRects)) + { + if (newReg != reg1) + miRegionCopy(newReg, reg1); + return 1; + } + + /* + * Region 1 completely subsumes region 2 + */ + if ((reg1->numRects == 1) && + (reg1->extents.x1 <= reg2->extents.x1) && + (reg1->extents.y1 <= reg2->extents.y1) && + (reg1->extents.x2 >= reg2->extents.x2) && + (reg1->extents.y2 >= reg2->extents.y2)) + { + if (newReg != reg1) + miRegionCopy(newReg, reg1); + return 1; + } + + /* + * Region 2 completely subsumes region 1 + */ + if ((reg2->numRects == 1) && + (reg2->extents.x1 <= reg1->extents.x1) && + (reg2->extents.y1 <= reg1->extents.y1) && + (reg2->extents.x2 >= reg1->extents.x2) && + (reg2->extents.y2 >= reg1->extents.y2)) + { + if (newReg != reg2) + miRegionCopy(newReg, reg2); + return 1; + } + + miRegionOp (newReg, reg1, reg2, (voidProcp) miUnionO, + (voidProcp) miUnionNonO, (voidProcp) miUnionNonO); + + newReg->extents.x1 = min(reg1->extents.x1, reg2->extents.x1); + newReg->extents.y1 = min(reg1->extents.y1, reg2->extents.y1); + newReg->extents.x2 = max(reg1->extents.x2, reg2->extents.x2); + newReg->extents.y2 = max(reg1->extents.y2, reg2->extents.y2); + + return 1; +} + + +/*====================================================================== + * Region Subtraction + *====================================================================*/ + +/*- + *----------------------------------------------------------------------- + * miSubtractNonO -- + * Deal with non-overlapping band for subtraction. Any parts from + * region 2 we discard. Anything from region 1 we add to the region. + * + * Results: + * None. + * + * Side Effects: + * pReg may be affected. + * + *----------------------------------------------------------------------- + */ +/* static void*/ +static +miSubtractNonO1 (pReg, r, rEnd, y1, y2) + register Region pReg; + register BoxPtr r; + BoxPtr rEnd; + register short y1; + register short y2; +{ + register BoxPtr pNextRect; + + pNextRect = &pReg->rects[pReg->numRects]; + + assert(y1<y2); + + while (r != rEnd) + { + assert(r->x1<r->x2); + MEMCHECK(pReg, pNextRect, pReg->rects); + pNextRect->x1 = r->x1; + pNextRect->y1 = y1; + pNextRect->x2 = r->x2; + pNextRect->y2 = y2; + pReg->numRects += 1; + pNextRect++; + + assert(pReg->numRects <= pReg->size); + + r++; + } + return 0; /* lint */ +} + +/*- + *----------------------------------------------------------------------- + * miSubtractO -- + * Overlapping band subtraction. x1 is the left-most point not yet + * checked. + * + * Results: + * None. + * + * Side Effects: + * pReg may have rectangles added to it. + * + *----------------------------------------------------------------------- + */ +/* static void*/ +static +miSubtractO (pReg, r1, r1End, r2, r2End, y1, y2) + register Region pReg; + register BoxPtr r1; + BoxPtr r1End; + register BoxPtr r2; + BoxPtr r2End; + register short y1; + register short y2; +{ + register BoxPtr pNextRect; + register int x1; + + x1 = r1->x1; + + assert(y1<y2); + pNextRect = &pReg->rects[pReg->numRects]; + + while ((r1 != r1End) && (r2 != r2End)) + { + if (r2->x2 <= x1) + { + /* + * Subtrahend missed the boat: go to next subtrahend. + */ + r2++; + } + else if (r2->x1 <= x1) + { + /* + * Subtrahend preceeds minuend: nuke left edge of minuend. + */ + x1 = r2->x2; + if (x1 >= r1->x2) + { + /* + * Minuend completely covered: advance to next minuend and + * reset left fence to edge of new minuend. + */ + r1++; + if (r1 != r1End) + x1 = r1->x1; + } + else + { + /* + * Subtrahend now used up since it doesn't extend beyond + * minuend + */ + r2++; + } + } + else if (r2->x1 < r1->x2) + { + /* + * Left part of subtrahend covers part of minuend: add uncovered + * part of minuend to region and skip to next subtrahend. + */ + assert(x1<r2->x1); + MEMCHECK(pReg, pNextRect, pReg->rects); + pNextRect->x1 = x1; + pNextRect->y1 = y1; + pNextRect->x2 = r2->x1; + pNextRect->y2 = y2; + pReg->numRects += 1; + pNextRect++; + + assert(pReg->numRects<=pReg->size); + + x1 = r2->x2; + if (x1 >= r1->x2) + { + /* + * Minuend used up: advance to new... + */ + r1++; + if (r1 != r1End) + x1 = r1->x1; + } + else + { + /* + * Subtrahend used up + */ + r2++; + } + } + else + { + /* + * Minuend used up: add any remaining piece before advancing. + */ + if (r1->x2 > x1) + { + MEMCHECK(pReg, pNextRect, pReg->rects); + pNextRect->x1 = x1; + pNextRect->y1 = y1; + pNextRect->x2 = r1->x2; + pNextRect->y2 = y2; + pReg->numRects += 1; + pNextRect++; + assert(pReg->numRects<=pReg->size); + } + r1++; + x1 = r1->x1; + } + } + + /* + * Add remaining minuend rectangles to region. + */ + while (r1 != r1End) + { + assert(x1<r1->x2); + MEMCHECK(pReg, pNextRect, pReg->rects); + pNextRect->x1 = x1; + pNextRect->y1 = y1; + pNextRect->x2 = r1->x2; + pNextRect->y2 = y2; + pReg->numRects += 1; + pNextRect++; + + assert(pReg->numRects<=pReg->size); + + r1++; + if (r1 != r1End) + { + x1 = r1->x1; + } + } + return 0; /* lint */ +} + +/*- + *----------------------------------------------------------------------- + * miSubtract -- + * Subtract regS from regM and leave the result in regD. + * S stands for subtrahend, M for minuend and D for difference. + * + * Results: + * TRUE. + * + * Side Effects: + * regD is overwritten. + * + *----------------------------------------------------------------------- + */ + +XSubtractRegion(regM, regS, regD) + Region regM; + Region regS; + register Region regD; +{ + /* check for trivial reject */ + if ( (!(regM->numRects)) || (!(regS->numRects)) || + (!EXTENTCHECK(®M->extents, ®S->extents)) ) + { + miRegionCopy(regD, regM); + return 1; + } + + miRegionOp (regD, regM, regS, (voidProcp) miSubtractO, + (voidProcp) miSubtractNonO1, (voidProcp) NULL); + + /* + * Can't alter newReg's extents before we call miRegionOp because + * it might be one of the source regions and miRegionOp depends + * on the extents of those regions being the unaltered. Besides, this + * way there's no checking against rectangles that will be nuked + * due to coalescing, so we have to examine fewer rectangles. + */ + miSetExtents (regD); + return 1; +} + +int +XXorRegion( sra, srb, dr ) + Region sra, srb, dr; +{ + Region tra, trb; + + if ((! (tra = XCreateRegion())) || (! (trb = XCreateRegion()))) + return 0; + (void) XSubtractRegion(sra,srb,tra); + (void) XSubtractRegion(srb,sra,trb); + (void) XUnionRegion(tra,trb,dr); + XDestroyRegion(tra); + XDestroyRegion(trb); + return 0; +} + +/* + * Check to see if the region is empty. Assumes a region is passed + * as a parameter + */ +int +XEmptyRegion( r ) + Region r; +{ + if( r->numRects == 0 ) return TRUE; + else return FALSE; +} + +/* + * Check to see if two regions are equal + */ +int +XEqualRegion( r1, r2 ) + Region r1, r2; +{ + int i; + + if( r1->numRects != r2->numRects ) return FALSE; + else if( r1->numRects == 0 ) return TRUE; + else if ( r1->extents.x1 != r2->extents.x1 ) return FALSE; + else if ( r1->extents.x2 != r2->extents.x2 ) return FALSE; + else if ( r1->extents.y1 != r2->extents.y1 ) return FALSE; + else if ( r1->extents.y2 != r2->extents.y2 ) return FALSE; + else for( i=0; i < r1->numRects; i++ ) { + if ( r1->rects[i].x1 != r2->rects[i].x1 ) return FALSE; + else if ( r1->rects[i].x2 != r2->rects[i].x2 ) return FALSE; + else if ( r1->rects[i].y1 != r2->rects[i].y1 ) return FALSE; + else if ( r1->rects[i].y2 != r2->rects[i].y2 ) return FALSE; + } + return TRUE; +} + +int +XPointInRegion( pRegion, x, y ) + Region pRegion; + int x, y; +{ + int i; + + if (pRegion->numRects == 0) + return FALSE; + if (!INBOX(pRegion->extents, x, y)) + return FALSE; + for (i=0; i<pRegion->numRects; i++) + { + if (INBOX (pRegion->rects[i], x, y)) + return TRUE; + } + return FALSE; +} + +int +XRectInRegion(region, rx, ry, rwidth, rheight) + register Region region; + int rx, ry; + unsigned int rwidth, rheight; +{ + register BoxPtr pbox; + register BoxPtr pboxEnd; + Box rect; + register BoxPtr prect = ▭ + int partIn, partOut; + + prect->x1 = rx; + prect->y1 = ry; + prect->x2 = rwidth + rx; + prect->y2 = rheight + ry; + + /* this is (just) a useful optimization */ + if ((region->numRects == 0) || !EXTENTCHECK(®ion->extents, prect)) + return(RectangleOut); + + partOut = FALSE; + partIn = FALSE; + + /* can stop when both partOut and partIn are TRUE, or we reach prect->y2 */ + for (pbox = region->rects, pboxEnd = pbox + region->numRects; + pbox < pboxEnd; + pbox++) + { + + if (pbox->y2 <= ry) + continue; /* getting up to speed or skipping remainder of band */ + + if (pbox->y1 > ry) + { + partOut = TRUE; /* missed part of rectangle above */ + if (partIn || (pbox->y1 >= prect->y2)) + break; + ry = pbox->y1; /* x guaranteed to be == prect->x1 */ + } + + if (pbox->x2 <= rx) + continue; /* not far enough over yet */ + + if (pbox->x1 > rx) + { + partOut = TRUE; /* missed part of rectangle to left */ + if (partIn) + break; + } + + if (pbox->x1 < prect->x2) + { + partIn = TRUE; /* definitely overlap */ + if (partOut) + break; + } + + if (pbox->x2 >= prect->x2) + { + ry = pbox->y2; /* finished with this band */ + if (ry >= prect->y2) + break; + rx = prect->x1; /* reset x out to left again */ + } else + { + /* + * Because boxes in a band are maximal width, if the first box + * to overlap the rectangle doesn't completely cover it in that + * band, the rectangle must be partially out, since some of it + * will be uncovered in that band. partIn will have been set true + * by now... + */ + break; + } + + } + + return(partIn ? ((ry < prect->y2) ? RectanglePart : RectangleIn) : + RectangleOut); +} diff --git a/src/RegstFlt.c b/src/RegstFlt.c new file mode 100644 index 00000000..901e5f30 --- /dev/null +++ b/src/RegstFlt.c @@ -0,0 +1,160 @@ +/* $Xorg: RegstFlt.c,v 1.5 2001/02/09 02:03:35 xorgcvs Exp $ */ + + /* + * Copyright 1990, 1991 by OMRON Corporation + * + * 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 OMRON not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. OMRON makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * OMRON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL OMRON 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 + * TORTUOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Author: Seiji Kuwari OMRON Corporation + * kuwa@omron.co.jp + * kuwa%omron.co.jp@uunet.uu.net + */ +/* + +Copyright 1990, 1991, 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. + +*/ + +#include "Xlibint.h" +#include "Xlcint.h" + +static void +_XFreeIMFilters(display) + Display *display; +{ + register XFilterEventList fl; + + while ((fl = display->im_filters)) { + display->im_filters = fl->next; + Xfree((char *)fl); + } +} + +/* + * Register a filter with the filter machinery by event mask. + */ +void +_XRegisterFilterByMask(display, window, event_mask, filter, client_data) + Display *display; + Window window; + unsigned long event_mask; + Bool (*filter)( +#if NeedNestedPrototypes + Display*, Window, XEvent*, XPointer +#endif + ); + XPointer client_data; +{ + XFilterEventRec *rec; + + rec = (XFilterEventList)Xmalloc(sizeof(XFilterEventRec)); + if (!rec) + return; + rec->window = window; + rec->event_mask = event_mask; + rec->start_type = 0; + rec->end_type = 0; + rec->filter = filter; + rec->client_data = client_data; + LockDisplay(display); + rec->next = display->im_filters; + display->im_filters = rec; + display->free_funcs->im_filters = _XFreeIMFilters; + UnlockDisplay(display); +} + +/* + * Register a filter with the filter machinery by type code. + */ +void +_XRegisterFilterByType(display, window, start_type, end_type, + filter, client_data) + Display *display; + Window window; + int start_type; + int end_type; + Bool (*filter)( +#if NeedNestedPrototypes + Display*, Window, XEvent*, XPointer +#endif + ); + XPointer client_data; +{ + XFilterEventRec *rec; + + rec = (XFilterEventList)Xmalloc(sizeof(XFilterEventRec)); + if (!rec) + return; + rec->window = window; + rec->event_mask = 0; + rec->start_type = start_type; + rec->end_type = end_type; + rec->filter = filter; + rec->client_data = client_data; + LockDisplay(display); + rec->next = display->im_filters; + display->im_filters = rec; + display->free_funcs->im_filters = _XFreeIMFilters; + UnlockDisplay(display); +} + +void +_XUnregisterFilter(display, window, filter, client_data) + Display *display; + Window window; + Bool (*filter)( +#if NeedNestedPrototypes + Display*, Window, XEvent*, XPointer +#endif + ); + XPointer client_data; +{ + register XFilterEventList *prev, fl; + + for (prev = &display->im_filters; (fl = *prev); ) { + if (fl->window == window && + fl->filter == filter && fl->client_data == client_data) { + *prev = fl->next; + Xfree((char *)fl); + } else + prev = &fl->next; + } +} diff --git a/src/RepWindow.c b/src/RepWindow.c new file mode 100644 index 00000000..ca1f6315 --- /dev/null +++ b/src/RepWindow.c @@ -0,0 +1,47 @@ +/* $Xorg: RepWindow.c,v 1.4 2001/02/09 02:03:36 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XReparentWindow(dpy, w, p, x, y) + register Display *dpy; + Window w, p; + int x, y; +{ + register xReparentWindowReq *req; + + LockDisplay(dpy); + GetReq(ReparentWindow, req); + req->window = w; + req->parent = p; + req->x = x; + req->y = y; + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} + diff --git a/src/RestackWs.c b/src/RestackWs.c new file mode 100644 index 00000000..1051fde6 --- /dev/null +++ b/src/RestackWs.c @@ -0,0 +1,67 @@ +/* $Xorg: RestackWs.c,v 1.4 2001/02/09 02:03:36 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XRestackWindows (dpy, windows, n) + register Display *dpy; + register Window *windows; + int n; + { + int i = 0; +#ifdef MUSTCOPY + unsigned long val = Below; /* needed for macro below */ +#endif + + LockDisplay(dpy); + while (windows++, ++i < n) { + register xConfigureWindowReq *req; + + GetReqExtra (ConfigureWindow, 8, req); + req->window = *windows; + req->mask = CWSibling | CWStackMode; +#ifdef MUSTCOPY + dpy->bufptr -= 8; + Data32 (dpy, (long *)(windows-1), 4); + Data32 (dpy, (long *)&val, 4); +#else + { + register CARD32 *values = (CARD32 *) + NEXTPTR(req,xConfigureWindowReq); + *values++ = *(windows-1); + *values = Below; + } +#endif /* MUSTCOPY */ + } + UnlockDisplay(dpy); + SyncHandle(); + return 1; + } + + + + diff --git a/src/RotProp.c b/src/RotProp.c new file mode 100644 index 00000000..36c3c1df --- /dev/null +++ b/src/RotProp.c @@ -0,0 +1,60 @@ +/* $Xorg: RotProp.c,v 1.4 2001/02/09 02:03:36 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XRotateWindowProperties(dpy, w, properties, nprops, npositions) + register Display *dpy; + Window w; + Atom *properties; + register int nprops; + int npositions; + { + register long nbytes; + register xRotatePropertiesReq *req; + + LockDisplay(dpy); + GetReq (RotateProperties, req); + req->window = w; + req->nAtoms = nprops; + req->nPositions = npositions; + + req->length += nprops; + nbytes = nprops << 2; +/* XXX Cray needs packing here.... */ + Data32 (dpy, (long *) properties, nbytes); + + + UnlockDisplay(dpy); + SyncHandle(); + return 1; + } + + + + + diff --git a/src/ScrResStr.c b/src/ScrResStr.c new file mode 100644 index 00000000..bd996871 --- /dev/null +++ b/src/ScrResStr.c @@ -0,0 +1,54 @@ +/* $Xorg: ScrResStr.c,v 1.4 2001/02/09 02:03:36 xorgcvs Exp $ */ +/* + +Copyright 1991, 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. + +*/ + +#include "Xlibint.h" +#include <X11/Xatom.h> + +char *XScreenResourceString(screen) + Screen *screen; +{ + Atom prop_name; + Atom actual_type; + int actual_format; + unsigned long nitems; + unsigned long leftover; + char *val = NULL; + + prop_name = XInternAtom(screen->display, "SCREEN_RESOURCES", True); + if (prop_name && + XGetWindowProperty(screen->display, screen->root, prop_name, + 0L, 100000000L, False, + XA_STRING, &actual_type, &actual_format, + &nitems, &leftover, + (unsigned char **) &val) == Success) { + if ((actual_type == XA_STRING) && (actual_format == 8)) + return val; + if (val) + Xfree(val); + } + return (char *)NULL; +} diff --git a/src/SelInput.c b/src/SelInput.c new file mode 100644 index 00000000..c42a6674 --- /dev/null +++ b/src/SelInput.c @@ -0,0 +1,46 @@ +/* $Xorg: SelInput.c,v 1.4 2001/02/09 02:03:36 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XSelectInput (dpy, w, mask) + register Display *dpy; + Window w; + long mask; +{ + register xChangeWindowAttributesReq *req; + + LockDisplay(dpy); + GetReqExtra (ChangeWindowAttributes, 4, req); + req->window = w; + req->valueMask = CWEventMask; + OneDataCard32 (dpy, NEXTPTR(req,xChangeWindowAttributesReq), mask); + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} + diff --git a/src/SendEvent.c b/src/SendEvent.c new file mode 100644 index 00000000..d853e273 --- /dev/null +++ b/src/SendEvent.c @@ -0,0 +1,73 @@ +/* $Xorg: SendEvent.c,v 1.4 2001/02/09 02:03:36 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#define NEED_EVENTS +#include "Xlibint.h" + +extern Status _XEventToWire(); +/* + * In order to avoid all images requiring _XEventToWire, we install the + * event converter here if it has never been installed. + */ +Status +XSendEvent(dpy, w, propagate, event_mask, event) + register Display *dpy; + Window w; + Bool propagate; + long event_mask; + XEvent *event; +{ + register xSendEventReq *req; + xEvent ev; + register Status (**fp)(); + Status status; + + LockDisplay (dpy); + + /* call through display to find proper conversion routine */ + + fp = &dpy->wire_vec[event->type & 0177]; + if (*fp == NULL) *fp = _XEventToWire; + status = (**fp)(dpy, event, &ev); + + if (status) { + GetReq(SendEvent, req); + req->destination = w; + req->propagate = propagate; + req->eventMask = event_mask; +#ifdef WORD64 + /* avoid quad-alignment problems */ + memcpy ((char *) req->eventdata, (char *) &ev, SIZEOF(xEvent)); +#else + req->event = ev; +#endif /* WORD64 */ + } + + UnlockDisplay(dpy); + SyncHandle(); + return(status); +} diff --git a/src/SetBack.c b/src/SetBack.c new file mode 100644 index 00000000..aea142c9 --- /dev/null +++ b/src/SetBack.c @@ -0,0 +1,43 @@ +/* $Xorg: SetBack.c,v 1.4 2001/02/09 02:03:36 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XSetBackground (dpy, gc, background) +register Display *dpy; +GC gc; +unsigned long background; /* CARD32 */ +{ + LockDisplay(dpy); + if (gc->values.background != background) { + gc->values.background = background; + gc->dirty |= GCBackground; + } + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} diff --git a/src/SetCRects.c b/src/SetCRects.c new file mode 100644 index 00000000..8f03b7de --- /dev/null +++ b/src/SetCRects.c @@ -0,0 +1,79 @@ +/* $Xorg: SetCRects.c,v 1.4 2001/02/09 02:03:36 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +/* can only call when display is locked. */ +void _XSetClipRectangles (dpy, gc, clip_x_origin, clip_y_origin, rectangles, n, + ordering) + register Display *dpy; + GC gc; + int clip_x_origin, clip_y_origin; + XRectangle *rectangles; + int n; + int ordering; +{ + register xSetClipRectanglesReq *req; + register long len; + unsigned long dirty; + register _XExtension *ext; + + GetReq (SetClipRectangles, req); + req->gc = gc->gid; + req->xOrigin = gc->values.clip_x_origin = clip_x_origin; + req->yOrigin = gc->values.clip_y_origin = clip_y_origin; + req->ordering = ordering; + len = ((long)n) << 1; + SetReqLen(req, len, 1); + len <<= 2; + Data16 (dpy, (short *) rectangles, len); + gc->rects = 1; + dirty = gc->dirty & ~(GCClipMask | GCClipXOrigin | GCClipYOrigin); + gc->dirty = GCClipMask | GCClipXOrigin | GCClipYOrigin; + /* call out to any extensions interested */ + for (ext = dpy->ext_procs; ext; ext = ext->next) + if (ext->flush_GC) (*ext->flush_GC)(dpy, gc, &ext->codes); + gc->dirty = dirty; +} + +XSetClipRectangles (dpy, gc, clip_x_origin, clip_y_origin, rectangles, n, + ordering) + register Display *dpy; + GC gc; + int clip_x_origin, clip_y_origin; + XRectangle *rectangles; + int n; + int ordering; +{ + LockDisplay(dpy); + _XSetClipRectangles (dpy, gc, clip_x_origin, clip_y_origin, rectangles, n, + ordering); + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} + diff --git a/src/SetClMask.c b/src/SetClMask.c new file mode 100644 index 00000000..75d97ab4 --- /dev/null +++ b/src/SetClMask.c @@ -0,0 +1,44 @@ +/* $Xorg: SetClMask.c,v 1.4 2001/02/09 02:03:36 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XSetClipMask (dpy, gc, mask) +register Display *dpy; +GC gc; +Pixmap mask; +{ + LockDisplay(dpy); + /* always update, since client may have changed pixmap contents */ + gc->values.clip_mask = mask; + gc->dirty |= GCClipMask; + gc->rects = 0; + _XFlushGCCache(dpy, gc); + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} diff --git a/src/SetClOrig.c b/src/SetClOrig.c new file mode 100644 index 00000000..c471234e --- /dev/null +++ b/src/SetClOrig.c @@ -0,0 +1,49 @@ +/* $Xorg: SetClOrig.c,v 1.4 2001/02/09 02:03:36 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XSetClipOrigin (dpy, gc, xorig, yorig) +register Display *dpy; +GC gc; +int xorig, yorig; +{ + XGCValues *gv = &gc->values; + + LockDisplay(dpy); + if (xorig != gv->clip_x_origin) { + gv->clip_x_origin = xorig; + gc->dirty |= GCClipXOrigin; + } + if (yorig != gv->clip_y_origin) { + gv->clip_y_origin = yorig; + gc->dirty |= GCClipYOrigin; + } + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} diff --git a/src/SetDashes.c b/src/SetDashes.c new file mode 100644 index 00000000..ce3a5e60 --- /dev/null +++ b/src/SetDashes.c @@ -0,0 +1,61 @@ +/* $Xorg: SetDashes.c,v 1.4 2001/02/09 02:03:36 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +#if NeedFunctionPrototypes +XSetDashes ( + register Display *dpy, + GC gc, + int dash_offset, + _Xconst char *list, + int n) +#else +XSetDashes (dpy, gc, dash_offset, list, n) + register Display *dpy; + GC gc; + int dash_offset; + char *list; + int n; +#endif + { + register xSetDashesReq *req; + + LockDisplay(dpy); + GetReq (SetDashes,req); + req->gc = gc->gid; + req->dashOffset = gc->values.dash_offset = dash_offset; + req->nDashes = n; + req->length += (n+3)>>2; + gc->dashes = 1; + gc->dirty &= ~(GCDashList | GCDashOffset); + Data (dpy, list, (long)n); + UnlockDisplay(dpy); + SyncHandle(); + return 1; + } + diff --git a/src/SetFPath.c b/src/SetFPath.c new file mode 100644 index 00000000..acf0a1d0 --- /dev/null +++ b/src/SetFPath.c @@ -0,0 +1,75 @@ +/* $Xorg: SetFPath.c,v 1.5 2001/02/09 02:03:36 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +#define safestrlen(s) ((s) ? strlen(s) : 0) + +int +XSetFontPath (dpy, directories, ndirs) +register Display *dpy; +char **directories; +int ndirs; +{ + register int n = 0; + register int i; + register int nbytes; + char *p; + register xSetFontPathReq *req; + int retCode; + + LockDisplay(dpy); + GetReq (SetFontPath, req); + req->nFonts = ndirs; + for (i = 0; i < ndirs; i++) { + n += safestrlen (directories[i]) + 1; + } + nbytes = (n + 3) & ~3; + req->length += nbytes >> 2; + if ((p = (char *) Xmalloc ((unsigned) nbytes))) { + /* + * pack into counted strings. + */ + char *tmp = p; + + for (i = 0; i < ndirs; i++) { + register int length = safestrlen (directories[i]); + *p = length; + memcpy (p + 1, directories[i], length); + p += length + 1; + } + Data (dpy, tmp, nbytes); + Xfree ((char *) tmp); + retCode = 1; + } + else + retCode = 0; + + UnlockDisplay(dpy); + SyncHandle(); + return (retCode); +} diff --git a/src/SetFont.c b/src/SetFont.c new file mode 100644 index 00000000..57f7294f --- /dev/null +++ b/src/SetFont.c @@ -0,0 +1,44 @@ +/* $Xorg: SetFont.c,v 1.4 2001/02/09 02:03:36 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XSetFont (dpy, gc, font) +register Display *dpy; +GC gc; +Font font; +{ + LockDisplay(dpy); + if (gc->values.font != font) { + gc->values.font = font; + gc->dirty |= GCFont; + _XFlushGCCache(dpy, gc); + } + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} diff --git a/src/SetFore.c b/src/SetFore.c new file mode 100644 index 00000000..d8773494 --- /dev/null +++ b/src/SetFore.c @@ -0,0 +1,43 @@ +/* $Xorg: SetFore.c,v 1.4 2001/02/09 02:03:36 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XSetForeground (dpy, gc, foreground) +register Display *dpy; +GC gc; +unsigned long foreground; /* CARD32 */ +{ + LockDisplay(dpy); + if (gc->values.foreground != foreground) { + gc->values.foreground = foreground; + gc->dirty |= GCForeground; + } + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} diff --git a/src/SetFunc.c b/src/SetFunc.c new file mode 100644 index 00000000..b4154672 --- /dev/null +++ b/src/SetFunc.c @@ -0,0 +1,43 @@ +/* $Xorg: SetFunc.c,v 1.4 2001/02/09 02:03:36 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XSetFunction (dpy, gc, function) +register Display *dpy; +GC gc; +int function; +{ + LockDisplay(dpy); + if (gc->values.function != function) { + gc->values.function = function; + gc->dirty |= GCFunction; + } + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} diff --git a/src/SetHints.c b/src/SetHints.c new file mode 100644 index 00000000..f8201921 --- /dev/null +++ b/src/SetHints.c @@ -0,0 +1,296 @@ +/* $Xorg: SetHints.c,v 1.5 2001/02/09 02:03:36 xorgcvs Exp $ */ + +/*********************************************************** + +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. + +******************************************************************/ + +#include <X11/Xlibint.h> +#include <X11/Xutil.h> +#include "Xatomtype.h" +#include <X11/Xatom.h> +#include <X11/Xos.h> + +#define safestrlen(s) ((s) ? strlen(s) : 0) + +XSetSizeHints(dpy, w, hints, property) /* old routine */ + Display *dpy; + Window w; + XSizeHints *hints; + Atom property; +{ + xPropSizeHints prop; + prop.flags = (hints->flags & (USPosition|USSize|PAllHints)); + prop.x = hints->x; + prop.y = hints->y; + prop.width = hints->width; + prop.height = hints->height; + prop.minWidth = hints->min_width; + prop.minHeight = hints->min_height; + prop.maxWidth = hints->max_width; + prop.maxHeight = hints->max_height; + prop.widthInc = hints->width_inc; + prop.heightInc = hints->height_inc; + prop.minAspectX = hints->min_aspect.x; + prop.minAspectY = hints->min_aspect.y; + prop.maxAspectX = hints->max_aspect.x; + prop.maxAspectY = hints->max_aspect.y; + return XChangeProperty (dpy, w, property, XA_WM_SIZE_HINTS, 32, + PropModeReplace, (unsigned char *) &prop, + OldNumPropSizeElements); +} + +/* + * XSetWMHints sets the property + * WM_HINTS type: WM_HINTS format:32 + */ + +XSetWMHints (dpy, w, wmhints) + Display *dpy; + Window w; + XWMHints *wmhints; +{ + xPropWMHints prop; + prop.flags = wmhints->flags; + prop.input = (wmhints->input == True ? 1 : 0); + prop.initialState = wmhints->initial_state; + prop.iconPixmap = wmhints->icon_pixmap; + prop.iconWindow = wmhints->icon_window; + prop.iconX = wmhints->icon_x; + prop.iconY = wmhints->icon_y; + prop.iconMask = wmhints->icon_mask; + prop.windowGroup = wmhints->window_group; + return XChangeProperty (dpy, w, XA_WM_HINTS, XA_WM_HINTS, 32, + PropModeReplace, (unsigned char *) &prop, + NumPropWMHintsElements); +} + + + +/* + * XSetZoomHints sets the property + * WM_ZOOM_HINTS type: WM_SIZE_HINTS format: 32 + */ + +XSetZoomHints (dpy, w, zhints) + Display *dpy; + Window w; + XSizeHints *zhints; +{ + return XSetSizeHints (dpy, w, zhints, XA_WM_ZOOM_HINTS); +} + + +/* + * XSetNormalHints sets the property + * WM_NORMAL_HINTS type: WM_SIZE_HINTS format: 32 + */ + +XSetNormalHints (dpy, w, hints) /* old routine */ + Display *dpy; + Window w; + XSizeHints *hints; +{ + return XSetSizeHints (dpy, w, hints, XA_WM_NORMAL_HINTS); +} + + + +/* + * Note, the following is one of the few cases were we really do want sizeof + * when examining a protocol structure. This is because the XChangeProperty + * routine will take care of converting to host to network data structures. + */ + +XSetIconSizes (dpy, w, list, count) + Display *dpy; + Window w; /* typically, root */ + XIconSize *list; + int count; /* number of items on the list */ +{ + register int i; + xPropIconSize *pp, *prop; +#define size_of_the_real_thing sizeof /* avoid grepping screwups */ + unsigned nbytes = count * size_of_the_real_thing(xPropIconSize); +#undef size_of_the_real_thing + if ((prop = pp = (xPropIconSize *) Xmalloc (nbytes))) { + for (i = 0; i < count; i++) { + pp->minWidth = list->min_width; + pp->minHeight = list->min_height; + pp->maxWidth = list->max_width; + pp->maxHeight = list->max_height; + pp->widthInc = list->width_inc; + pp->heightInc = list->height_inc; + pp += 1; + list += 1; + } + XChangeProperty (dpy, w, XA_WM_ICON_SIZE, XA_WM_ICON_SIZE, 32, + PropModeReplace, (unsigned char *) prop, + count * NumPropIconSizeElements); + Xfree ((char *)prop); + } + return 1; +} + +XSetCommand (dpy, w, argv, argc) + Display *dpy; + Window w; + char **argv; + int argc; +{ + register int i; + register int nbytes; + register char *buf, *bp; + for (i = 0, nbytes = 0; i < argc; i++) { + nbytes += safestrlen(argv[i]) + 1; + } + if ((bp = buf = Xmalloc((unsigned) nbytes))) { + /* copy arguments into single buffer */ + for (i = 0; i < argc; i++) { + if (argv[i]) { + (void) strcpy(bp, argv[i]); + bp += strlen(argv[i]) + 1; + } + else + *bp++ = '\0'; + } + XChangeProperty (dpy, w, XA_WM_COMMAND, XA_STRING, 8, + PropModeReplace, (unsigned char *)buf, nbytes); + Xfree(buf); + } + return 1; +} +/* + * XSetStandardProperties sets the following properties: + * WM_NAME type: STRING format: 8 + * WM_ICON_NAME type: STRING format: 8 + * WM_HINTS type: WM_HINTS format: 32 + * WM_COMMAND type: STRING + * WM_NORMAL_HINTS type: WM_SIZE_HINTS format: 32 + */ + +#if NeedFunctionPrototypes +XSetStandardProperties ( + Display *dpy, + Window w, /* window to decorate */ + _Xconst char *name, /* name of application */ + _Xconst char *icon_string,/* name string for icon */ + Pixmap icon_pixmap, /* pixmap to use as icon, or None */ + char **argv, /* command to be used to restart application */ + int argc, /* count of arguments */ + XSizeHints *hints) /* size hints for window in its normal state */ +#else +XSetStandardProperties (dpy, w, name, icon_string, icon_pixmap, argv, argc, hints) + Display *dpy; + Window w; /* window to decorate */ + char *name; /* name of application */ + char *icon_string; /* name string for icon */ + Pixmap icon_pixmap; /* pixmap to use as icon, or None */ + char **argv; /* command to be used to restart application */ + int argc; /* count of arguments */ + XSizeHints *hints; /* size hints for window in its normal state */ +#endif +{ + XWMHints phints; + phints.flags = 0; + + if (name != NULL) XStoreName (dpy, w, name); + + if (icon_string != NULL) { + XChangeProperty (dpy, w, XA_WM_ICON_NAME, XA_STRING, 8, + PropModeReplace, (unsigned char *)icon_string, safestrlen(icon_string)); + } + + if (icon_pixmap != None) { + phints.icon_pixmap = icon_pixmap; + phints.flags |= IconPixmapHint; + } + if (argv != NULL) XSetCommand(dpy, w, argv, argc); + + if (hints != NULL) XSetNormalHints(dpy, w, hints); + + if (phints.flags != 0) XSetWMHints(dpy, w, &phints); + + return 1; +} + +XSetTransientForHint(dpy, w, propWindow) + Display *dpy; + Window w; + Window propWindow; +{ + return XChangeProperty(dpy, w, XA_WM_TRANSIENT_FOR, XA_WINDOW, 32, + PropModeReplace, (unsigned char *) &propWindow, 1); +} + +XSetClassHint(dpy, w, classhint) + Display *dpy; + Window w; + XClassHint *classhint; +{ + char *class_string; + char *s; + int len_nm, len_cl; + + len_nm = safestrlen(classhint->res_name); + len_cl = safestrlen(classhint->res_class); + if ((class_string = s = Xmalloc((unsigned) (len_nm + len_cl + 2)))) { + if (len_nm) { + strcpy(s, classhint->res_name); + s += len_nm + 1; + } + else + *s++ = '\0'; + if (len_cl) + strcpy(s, classhint->res_class); + else + *s = '\0'; + XChangeProperty(dpy, w, XA_WM_CLASS, XA_STRING, 8, + PropModeReplace, (unsigned char *) class_string, + len_nm+len_cl+2); + Xfree(class_string); + } + return 1; +} diff --git a/src/SetIFocus.c b/src/SetIFocus.c new file mode 100644 index 00000000..550a8cba --- /dev/null +++ b/src/SetIFocus.c @@ -0,0 +1,47 @@ +/* $Xorg: SetIFocus.c,v 1.4 2001/02/09 02:03:36 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XSetInputFocus(dpy, focus, revert_to, time) + register Display *dpy; + Window focus; + int revert_to; + Time time; +{ + register xSetInputFocusReq *req; + + LockDisplay(dpy); + GetReq(SetInputFocus, req); + req->focus = focus; + req->revertTo = revert_to; + req->time = time; + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} + diff --git a/src/SetLStyle.c b/src/SetLStyle.c new file mode 100644 index 00000000..a0352407 --- /dev/null +++ b/src/SetLStyle.c @@ -0,0 +1,60 @@ +/* $Xorg: SetLStyle.c,v 1.4 2001/02/09 02:03:36 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XSetLineAttributes(dpy, gc, linewidth, linestyle, capstyle, joinstyle) +register Display *dpy; +GC gc; +unsigned int linewidth; /* CARD16 */ +int linestyle; +int capstyle; +int joinstyle; +{ + XGCValues *gv = &gc->values; + + LockDisplay(dpy); + if (linewidth != gv->line_width) { + gv->line_width = linewidth; + gc->dirty |= GCLineWidth; + } + if (linestyle != gv->line_style) { + gv->line_style = linestyle; + gc->dirty |= GCLineStyle; + } + if (capstyle != gv->cap_style) { + gv->cap_style = capstyle; + gc->dirty |= GCCapStyle; + } + if (joinstyle != gv->join_style) { + gv->join_style = joinstyle; + gc->dirty |= GCJoinStyle; + } + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} diff --git a/src/SetLocale.c b/src/SetLocale.c new file mode 100644 index 00000000..faa72941 --- /dev/null +++ b/src/SetLocale.c @@ -0,0 +1,230 @@ +/* $Xorg: SetLocale.c,v 1.4 2001/02/09 02:03:36 xorgcvs Exp $ */ + +/* + * Copyright 1990, 1991 by OMRON Corporation, NTT Software Corporation, + * and Nippon Telegraph and Telephone Corporation + * + * 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 names of OMRON, NTT Software, and NTT + * not be used in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. OMRON, NTT Software, + * and NTT make no representations about the suitability of this + * software for any purpose. It is provided "as is" without express or + * implied warranty. + * + * OMRON, NTT SOFTWARE, AND NTT, DISCLAIM ALL WARRANTIES WITH REGARD + * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL OMRON, NTT SOFTWARE, OR NTT, 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. + * + * Authors: Li Yuhong OMRON Corporation + * Tetsuya Kato NTT Software Corporation + * Hiroshi Kuribayashi OMRON Corporation + * + */ +/* + +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. + +*/ + +#include "Xlibint.h" +#include "Xlcint.h" +#include <X11/Xlocale.h> +#include <X11/Xos.h> + +#ifdef X_LOCALE + +/* alternative setlocale() for when the OS does not provide one */ + +#ifdef X_NOT_STDC_ENV +extern char *getenv(); +#endif + +#if NeedFunctionPrototypes +char * +_Xsetlocale( + int category, + _Xconst char *name +) +#else +char * +_Xsetlocale(category, name) + int category; + char *name; +#endif +{ + static char *xsl_name; + char *old_name; + XrmMethods methods; + XPointer state; + + if (category != LC_CTYPE && category != LC_ALL) + return NULL; + if (!name) { + if (xsl_name) + return xsl_name; + return "C"; + } + if (!*name) + name = getenv("LC_CTYPE"); + if (!name || !*name) + name = getenv("LANG"); + if (!name || !*name || !_XOpenLC(name)) + name = "C"; + old_name = xsl_name; + xsl_name = (char *)name; + methods = _XrmInitParseInfo(&state); + xsl_name = old_name; + if (!methods) + return NULL; + name = (*methods->lcname)(state); + xsl_name = Xmalloc(strlen(name) + 1); + if (!xsl_name) { + xsl_name = old_name; + (*methods->destroy)(state); + return NULL; + } + strcpy(xsl_name, name); + if (old_name) + Xfree(old_name); + (*methods->destroy)(state); + return xsl_name; +} + +#else /* X_LOCALE */ + +/* + * _XlcMapOSLocaleName is an implementation dependent routine that derives + * the LC_CTYPE locale name as used in the sample implementation from that + * returned by setlocale. + * + * Should match the code in Xt ExtractLocaleName. + * + * This function name is a bit of a misnomer. Even the siname parameter + * name is a misnomer. On most modern operating systems this function is + * a no-op, simply returning the osname; but on older operating systems + * like Ultrix, or HPUX 9.x and earlier, when you set LANG=german.88591 + * then the string returned by setlocale(LC_ALL, "") will look something + * like: "german.88591 german.88591 ... german.88591". Then this function + * will pick out the LC_CTYPE component and return a pointer to that. + */ + +char * +_XlcMapOSLocaleName(osname, siname) + char *osname; + char *siname; +{ +#if defined(hpux) || defined(CSRG_BASED) || defined(sun) || defined(SVR4) || defined(sgi) || defined(__osf__) || defined(AIXV3) || defined(ultrix) || defined(WIN32) +#ifdef hpux +#ifndef _LastCategory +/* HPUX 9 and earlier */ +#define SKIPCOUNT 2 +#define STARTCHAR ':' +#define ENDCHAR ';' +#else +/* HPUX 10 */ +#define ENDCHAR ' ' +#endif +#else +#ifdef ultrix +#define SKIPCOUNT 2 +#define STARTCHAR '\001' +#define ENDCHAR '\001' +#else +#ifdef WIN32 +#define SKIPCOUNT 1 +#define STARTCHAR '=' +#define ENDCHAR ';' +#define WHITEFILL +#else +#if defined(__osf__) || (defined(AIXV3) && !defined(AIXV4)) +#define STARTCHAR ' ' +#define ENDCHAR ' ' +#else +#if !defined(sun) || defined(SVR4) +#define STARTCHAR '/' +#endif +#define ENDCHAR '/' +#endif +#endif +#endif +#endif + + char *start; + char *end; + int len; +#ifdef SKIPCOUNT + int n; +#endif + + start = osname; +#ifdef SKIPCOUNT + for (n = SKIPCOUNT; + --n >= 0 && start && (start = strchr (start, STARTCHAR)); + start++) + ; + if (!start) + start = osname; +#endif +#ifdef STARTCHAR + if (start && (start = strchr (start, STARTCHAR))) { + start++; +#endif + if (end = strchr (start, ENDCHAR)) { + len = end - start; + strncpy(siname, start, len); + *(siname + len) = '\0'; +#ifdef WHITEFILL + for (start = siname; start = strchr(start, ' '); ) + *start++ = '-'; +#endif + return siname; +#ifdef STARTCHAR + } +#endif + } +#ifdef WHITEFILL + if (strchr(osname, ' ')) { + strcpy(siname, osname); + for (start = siname; start = strchr(start, ' '); ) + *start++ = '-'; + return siname; + } +#endif +#undef STARTCHAR +#undef ENDCHAR +#undef WHITEFILL +#endif + return osname; +} + +#endif /* X_LOCALE */ diff --git a/src/SetNrmHint.c b/src/SetNrmHint.c new file mode 100644 index 00000000..d8511a6f --- /dev/null +++ b/src/SetNrmHint.c @@ -0,0 +1,108 @@ +/* $Xorg: SetNrmHint.c,v 1.4 2001/02/09 02:03:36 xorgcvs Exp $ */ + +/*********************************************************** +Copyright 1988 by Wyse Technology, Inc., San Jose, Ca, +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 Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL AND WYSE DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO +EVENT SHALL DIGITAL OR WYSE 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. + +******************************************************************/ +/* + +Copyright 1987, 1988, 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. + +*/ + +#include <X11/Xlibint.h> +#include <X11/Xutil.h> +#include "Xatomtype.h" +#include <X11/Xatom.h> +#include <X11/Xos.h> + +void XSetWMSizeHints (dpy, w, hints, prop) + Display *dpy; + Window w; + XSizeHints *hints; + Atom prop; +{ + xPropSizeHints data; + + data.flags = (hints->flags & + (USPosition|USSize|PPosition|PSize|PMinSize|PMaxSize| + PResizeInc|PAspect|PBaseSize|PWinGravity)); + + /* + * The x, y, width, and height fields are obsolete; but, applications + * that want to work with old window managers might set them. + */ + data.x = hints->x; + data.y = hints->y; + data.width = hints->width; + data.height = hints->height; + + data.minWidth = hints->min_width; + data.minHeight = hints->min_height; + data.maxWidth = hints->max_width; + data.maxHeight = hints->max_height; + data.widthInc = hints->width_inc; + data.heightInc = hints->height_inc; + data.minAspectX = hints->min_aspect.x; + data.minAspectY = hints->min_aspect.y; + data.maxAspectX = hints->max_aspect.x; + data.maxAspectY = hints->max_aspect.y; + data.baseWidth = hints->base_width; + data.baseHeight = hints->base_height; + data.winGravity = hints->win_gravity; + + XChangeProperty (dpy, w, prop, XA_WM_SIZE_HINTS, 32, + PropModeReplace, (unsigned char *) &data, + NumPropSizeElements); +} + + +void XSetWMNormalHints (dpy, w, hints) + Display *dpy; + Window w; + XSizeHints *hints; +{ + XSetWMSizeHints (dpy, w, hints, XA_WM_NORMAL_HINTS); +} + diff --git a/src/SetPMask.c b/src/SetPMask.c new file mode 100644 index 00000000..d712c12b --- /dev/null +++ b/src/SetPMask.c @@ -0,0 +1,43 @@ +/* $Xorg: SetPMask.c,v 1.4 2001/02/09 02:03:36 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XSetPlaneMask (dpy, gc, planemask) +register Display *dpy; +GC gc; +unsigned long planemask; /* CARD32 */ +{ + LockDisplay(dpy); + if (gc->values.plane_mask != planemask) { + gc->values.plane_mask = planemask; + gc->dirty |= GCPlaneMask; + } + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} diff --git a/src/SetPntMap.c b/src/SetPntMap.c new file mode 100644 index 00000000..52971616 --- /dev/null +++ b/src/SetPntMap.c @@ -0,0 +1,84 @@ +/* $Xorg: SetPntMap.c,v 1.4 2001/02/09 02:03:36 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#define NEED_REPLIES + +#include "Xlibint.h" +/* returns either DeviceMappingSuccess or DeviceMappingBusy */ + +#if NeedFunctionPrototypes +int XSetPointerMapping ( + register Display *dpy, + _Xconst unsigned char *map, + int nmaps) +#else +int XSetPointerMapping (dpy, map, nmaps) + register Display *dpy; + unsigned char *map; + int nmaps; +#endif + { + register xSetPointerMappingReq *req; + xSetPointerMappingReply rep; + + LockDisplay(dpy); + GetReq (SetPointerMapping, req); + req->nElts = nmaps; + req->length += (nmaps + 3)>>2; + Data (dpy, (char *)map, (long) nmaps); + if (_XReply (dpy, (xReply *)&rep, 0, xFalse) == 0) + rep.success = MappingSuccess; + UnlockDisplay(dpy); + SyncHandle(); + return ((int) rep.success); + } + +XChangeKeyboardMapping (dpy, first_keycode, keysyms_per_keycode, + keysyms, nkeycodes) + register Display *dpy; + int first_keycode; + int keysyms_per_keycode; + KeySym *keysyms; + int nkeycodes; + { + register long nbytes; + register xChangeKeyboardMappingReq *req; + + LockDisplay(dpy); + GetReq (ChangeKeyboardMapping, req); + req->firstKeyCode = first_keycode; + req->keyCodes = nkeycodes; + req->keySymsPerKeyCode = keysyms_per_keycode; + req->firstKeyCode = first_keycode; + req->length += nkeycodes * keysyms_per_keycode; + nbytes = keysyms_per_keycode * nkeycodes * 4; + Data32 (dpy, (long *)keysyms, nbytes); + UnlockDisplay(dpy); + SyncHandle(); + return 0; + } + diff --git a/src/SetRGBCMap.c b/src/SetRGBCMap.c new file mode 100644 index 00000000..0523f0ba --- /dev/null +++ b/src/SetRGBCMap.c @@ -0,0 +1,98 @@ +/* $Xorg: SetRGBCMap.c,v 1.4 2001/02/09 02:03:36 xorgcvs Exp $ */ +/* + +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. + +*/ + + +#include <X11/Xlibint.h> +#include <X11/Xutil.h> +#include "Xatomtype.h" +#include <X11/Xatom.h> + +void XSetRGBColormaps (dpy, w, cmaps, count, property) + Display *dpy; + Window w; + XStandardColormap *cmaps; + int count; + Atom property; /* XA_RGB_BEST_MAP, etc. */ +{ + register int i; /* iterator variable */ + register xPropStandardColormap *map; /* tmp variable, data in prop */ + register XStandardColormap *cmap; /* tmp variable, user data */ + xPropStandardColormap *data, tmpdata; /* scratch data */ + int mode = PropModeReplace; /* for partial writes */ + Bool alloced_scratch_space; /* do we need to free? */ + + + if (count < 1) return; + + /* + * if doing more than one, allocate scratch space for it + */ + if ((count > 1) && ((data = ((xPropStandardColormap *) + Xmalloc(count*sizeof(xPropStandardColormap)))) + != NULL)) { + alloced_scratch_space = True; + } else { + data = &tmpdata; + alloced_scratch_space = False; + } + + + /* + * Do the iteration. If using temp space put out each part of the prop; + * otherwise, wait until the end and blast it all at once. + */ + for (i = count, map = data, cmap = cmaps; i > 0; i--, cmap++) { + map->colormap = cmap->colormap; + map->red_max = cmap->red_max; + map->red_mult = cmap->red_mult; + map->green_max = cmap->green_max; + map->green_mult = cmap->green_mult; + map->blue_max = cmap->blue_max; + map->blue_mult = cmap->blue_mult; + map->base_pixel = cmap->base_pixel; + map->visualid = cmap->visualid; + map->killid = cmap->killid; + + if (alloced_scratch_space) { + map++; + } else { + XChangeProperty (dpy, w, property, XA_RGB_COLOR_MAP, 32, mode, + (unsigned char *) data, + NumPropStandardColormapElements); + mode = PropModeAppend; + } + } + + if (alloced_scratch_space) { + XChangeProperty (dpy, w, property, XA_RGB_COLOR_MAP, 32, + PropModeReplace, (unsigned char *) data, + (int) (count * NumPropStandardColormapElements)); + Xfree ((char *) data); + } +} diff --git a/src/SetSOwner.c b/src/SetSOwner.c new file mode 100644 index 00000000..67fc6ba2 --- /dev/null +++ b/src/SetSOwner.c @@ -0,0 +1,46 @@ +/* $Xorg: SetSOwner.c,v 1.4 2001/02/09 02:03:36 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XSetSelectionOwner(dpy, selection, owner, time) +register Display *dpy; +Atom selection; +Window owner; +Time time; +{ + register xSetSelectionOwnerReq *req; + + LockDisplay(dpy); + GetReq(SetSelectionOwner,req); + req->selection = selection; + req->window = owner; + req->time = time; + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} diff --git a/src/SetSSaver.c b/src/SetSSaver.c new file mode 100644 index 00000000..42ca05b0 --- /dev/null +++ b/src/SetSSaver.c @@ -0,0 +1,47 @@ +/* $Xorg: SetSSaver.c,v 1.4 2001/02/09 02:03:36 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XSetScreenSaver(dpy, timeout, interval, prefer_blank, allow_exp) + register Display *dpy; + int timeout, interval, prefer_blank, allow_exp; + +{ + register xSetScreenSaverReq *req; + + LockDisplay(dpy); + GetReq(SetScreenSaver, req); + req->timeout = timeout; + req->interval = interval; + req->preferBlank = prefer_blank; + req->allowExpose = allow_exp; + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} + diff --git a/src/SetStCmap.c b/src/SetStCmap.c new file mode 100644 index 00000000..86ff4c8e --- /dev/null +++ b/src/SetStCmap.c @@ -0,0 +1,90 @@ +/* $Xorg: SetStCmap.c,v 1.4 2001/02/09 02:03:36 xorgcvs Exp $ */ + +/*********************************************************** + +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. + +******************************************************************/ + +#include <X11/Xlibint.h> +#include <X11/Xutil.h> +#include "Xatomtype.h" +#include <X11/Xatom.h> + +/* + * WARNING + * + * This is a pre-ICCCM routine. It must not reference any of the new fields + * in the XStandardColormap structure. + */ + +void XSetStandardColormap(dpy, w, cmap, property) + Display *dpy; + Window w; + XStandardColormap *cmap; + Atom property; /* XA_RGB_BEST_MAP, etc. */ +{ + Screen *sp; + XStandardColormap stdcmap; + + sp = _XScreenOfWindow (dpy, w); + if (!sp) { + /* already caught the XGetGeometry error in _XScreenOfWindow */ + return; + } + + stdcmap.colormap = cmap->colormap; + stdcmap.red_max = cmap->red_max; + stdcmap.red_mult = cmap->red_mult; + stdcmap.green_max = cmap->green_max; + stdcmap.green_mult = cmap->green_mult; + stdcmap.blue_max = cmap->blue_max; + stdcmap.blue_mult = cmap->blue_mult; + stdcmap.base_pixel = cmap->base_pixel; + stdcmap.visualid = sp->root_visual->visualid; + stdcmap.killid = None; /* don't know how to kill this one */ + + XSetRGBColormaps (dpy, w, &stdcmap, 1, property); + return; +} diff --git a/src/SetState.c b/src/SetState.c new file mode 100644 index 00000000..ad91d8fa --- /dev/null +++ b/src/SetState.c @@ -0,0 +1,60 @@ +/* $Xorg: SetState.c,v 1.4 2001/02/09 02:03:36 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XSetState(dpy, gc, foreground, background, function, planemask) +register Display *dpy; +GC gc; +int function; +unsigned long planemask; +unsigned long foreground, background; +{ + XGCValues *gv = &gc->values; + + LockDisplay(dpy); + + if (function != gv->function) { + gv->function = function; + gc->dirty |= GCFunction; + } + if (planemask != gv->plane_mask) { + gv->plane_mask = planemask; + gc->dirty |= GCPlaneMask; + } + if (foreground != gv->foreground) { + gv->foreground = foreground; + gc->dirty |= GCForeground; + } + if (background != gv->background) { + gv->background = background; + gc->dirty |= GCBackground; + } + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} diff --git a/src/SetStip.c b/src/SetStip.c new file mode 100644 index 00000000..3c6948f3 --- /dev/null +++ b/src/SetStip.c @@ -0,0 +1,43 @@ +/* $Xorg: SetStip.c,v 1.4 2001/02/09 02:03:36 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XSetStipple (dpy, gc, stipple) +register Display *dpy; +GC gc; +Pixmap stipple; +{ + LockDisplay(dpy); + /* always update, since client may have changed pixmap contents */ + gc->values.stipple = stipple; + gc->dirty |= GCStipple; + _XFlushGCCache(dpy, gc); + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} diff --git a/src/SetTSOrig.c b/src/SetTSOrig.c new file mode 100644 index 00000000..6f6a2bad --- /dev/null +++ b/src/SetTSOrig.c @@ -0,0 +1,49 @@ +/* $Xorg: SetTSOrig.c,v 1.4 2001/02/09 02:03:36 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XSetTSOrigin (dpy, gc, x, y) +register Display *dpy; +GC gc; +int x, y; +{ + XGCValues *gv = &gc->values; + + LockDisplay(dpy); + if (x != gv->ts_x_origin) { + gv->ts_x_origin = x; + gc->dirty |= GCTileStipXOrigin; + } + if (y != gv->ts_y_origin) { + gv->ts_y_origin = y; + gc->dirty |= GCTileStipYOrigin; + } + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} diff --git a/src/SetTile.c b/src/SetTile.c new file mode 100644 index 00000000..296e74aa --- /dev/null +++ b/src/SetTile.c @@ -0,0 +1,43 @@ +/* $Xorg: SetTile.c,v 1.4 2001/02/09 02:03:36 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XSetTile (dpy, gc, tile) +register Display *dpy; +GC gc; +Pixmap tile; +{ + LockDisplay(dpy); + /* always update, since client may have changed pixmap contents */ + gc->values.tile = tile; + gc->dirty |= GCTile; + _XFlushGCCache(dpy, gc); + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} diff --git a/src/SetTxtProp.c b/src/SetTxtProp.c new file mode 100644 index 00000000..73bee7e1 --- /dev/null +++ b/src/SetTxtProp.c @@ -0,0 +1,91 @@ +/* $Xorg: SetTxtProp.c,v 1.4 2001/02/09 02:03:36 xorgcvs Exp $ */ +/*********************************************************** +Copyright 1988 by Wyse Technology, Inc., San Jose, Ca. + + 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 Wyse not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +WYSE 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. + +******************************************************************/ +/* + +Copyright 1988, 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. + +*/ + +#include <X11/Xlibint.h> +#include <X11/Xatom.h> +#include <X11/Xutil.h> +#include <X11/Xos.h> +#include <stdio.h> + +void XSetTextProperty (dpy, w, tp, property) + Display *dpy; + Window w; + Atom property; + XTextProperty *tp; +{ + XChangeProperty (dpy, w, property, tp->encoding, tp->format, + PropModeReplace, tp->value, tp->nitems); +} + +void XSetWMName (dpy, w, tp) + Display *dpy; + Window w; + XTextProperty *tp; +{ + XSetTextProperty (dpy, w, tp, XA_WM_NAME); +} + +void XSetWMIconName (dpy, w, tp) + Display *dpy; + Window w; + XTextProperty *tp; +{ + XSetTextProperty (dpy, w, tp, XA_WM_ICON_NAME); +} + +void XSetWMClientMachine (dpy, w, tp) + Display *dpy; + Window w; + XTextProperty *tp; +{ + XSetTextProperty (dpy, w, tp, XA_WM_CLIENT_MACHINE); +} + diff --git a/src/SetWMCMapW.c b/src/SetWMCMapW.c new file mode 100644 index 00000000..bf56a023 --- /dev/null +++ b/src/SetWMCMapW.c @@ -0,0 +1,72 @@ +/* $Xorg: SetWMCMapW.c,v 1.4 2001/02/09 02:03:36 xorgcvs Exp $ */ + +/*********************************************************** + +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. + +******************************************************************/ + +#include "Xlibint.h" +#include <X11/Xatom.h> + +/* + * XSetWMProtocols sets the property + * WM_COLORMAP_WINDOWS type: WINDOW format:32 + */ + +Status XSetWMColormapWindows (dpy, w, windows, count) + Display *dpy; + Window w; + Window *windows; + int count; +{ + Atom prop; + + prop = XInternAtom (dpy, "WM_COLORMAP_WINDOWS", False); + if (prop == None) return False; + + XChangeProperty (dpy, w, prop, XA_WINDOW, 32, + PropModeReplace, (unsigned char *) windows, count); + return True; +} diff --git a/src/SetWMProto.c b/src/SetWMProto.c new file mode 100644 index 00000000..15ebd76a --- /dev/null +++ b/src/SetWMProto.c @@ -0,0 +1,72 @@ +/* $Xorg: SetWMProto.c,v 1.4 2001/02/09 02:03:36 xorgcvs Exp $ */ + +/*********************************************************** + +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. + +******************************************************************/ + +#include "Xlibint.h" +#include <X11/Xatom.h> + +/* + * XSetWMProtocols sets the property + * WM_PROTOCOLS type: ATOM format: 32 + */ + +Status XSetWMProtocols (dpy, w, protocols, count) + Display *dpy; + Window w; + Atom *protocols; + int count; +{ + Atom prop; + + prop = XInternAtom (dpy, "WM_PROTOCOLS", False); + if (prop == None) return False; + + XChangeProperty (dpy, w, prop, XA_ATOM, 32, + PropModeReplace, (unsigned char *) protocols, count); + return True; +} diff --git a/src/StBytes.c b/src/StBytes.c new file mode 100644 index 00000000..880745f3 --- /dev/null +++ b/src/StBytes.c @@ -0,0 +1,114 @@ +/* $Xorg: StBytes.c,v 1.4 2001/02/09 02:03:36 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include <X11/Xlibint.h> +#include <X11/Xatom.h> + +/* insulate predefined atom numbers from cut routines */ +static Atom n_to_atom[8] = { + XA_CUT_BUFFER0, + XA_CUT_BUFFER1, + XA_CUT_BUFFER2, + XA_CUT_BUFFER3, + XA_CUT_BUFFER4, + XA_CUT_BUFFER5, + XA_CUT_BUFFER6, + XA_CUT_BUFFER7}; + +XRotateBuffers (dpy, rotate) + register Display *dpy; + int rotate; +{ + return XRotateWindowProperties(dpy, RootWindow(dpy, 0), n_to_atom, 8, rotate); +} + +char *XFetchBuffer (dpy, nbytes, buffer) + register Display *dpy; + int *nbytes; + register int buffer; +{ + Atom actual_type; + int actual_format; + unsigned long nitems; + unsigned long leftover; + unsigned char *data; + *nbytes = 0; + if ((buffer < 0) || (buffer > 7)) return (NULL); +/* XXX should be (sizeof (maxint) - 1)/4 */ + if (XGetWindowProperty(dpy, RootWindow(dpy, 0), n_to_atom[buffer], + 0L, 10000000L, False, XA_STRING, + &actual_type, &actual_format, &nitems, &leftover, &data) != Success) { + return (NULL); + } + if ( (actual_type == XA_STRING) && (actual_format != 32) ) { + *nbytes = nitems; + return((char *)data); + } + if ((char *) data != NULL) Xfree ((char *)data); + return(NULL); +} + +char *XFetchBytes (dpy, nbytes) + register Display *dpy; + int *nbytes; +{ + return (XFetchBuffer (dpy, nbytes, 0)); +} + +#if NeedFunctionPrototypes +XStoreBuffer ( + register Display *dpy, + _Xconst char *bytes, + int nbytes, + register int buffer) +#else +XStoreBuffer (dpy, bytes, nbytes, buffer) + register Display *dpy; + char *bytes; + int nbytes; + register int buffer; +#endif +{ + if ((buffer < 0) || (buffer > 7)) return 0; + return XChangeProperty(dpy, RootWindow(dpy, 0), n_to_atom[buffer], + XA_STRING, 8, PropModeReplace, (unsigned char *) bytes, nbytes); +} + +#if NeedFunctionPrototypes +XStoreBytes ( + register Display *dpy, + _Xconst char *bytes, + int nbytes) +#else +XStoreBytes (dpy, bytes, nbytes) + register Display *dpy; + char *bytes; + int nbytes; +#endif +{ + return XStoreBuffer (dpy, bytes, nbytes, 0); +} diff --git a/src/StColor.c b/src/StColor.c new file mode 100644 index 00000000..332fdf49 --- /dev/null +++ b/src/StColor.c @@ -0,0 +1,67 @@ +/* $Xorg: StColor.c,v 1.4 2001/02/09 02:03:36 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XStoreColor(dpy, cmap, def) +register Display *dpy; +Colormap cmap; +XColor *def; +{ + xColorItem *citem; + register xStoreColorsReq *req; +#ifdef MUSTCOPY + xColorItem citemdata; + long len = SIZEOF(xColorItem); + + citem = &citemdata; +#endif /* MUSTCOPY */ + + LockDisplay(dpy); + GetReqExtra(StoreColors, SIZEOF(xColorItem), req); /* assume size is 4*n */ + + req->cmap = cmap; + +#ifndef MUSTCOPY + citem = (xColorItem *) NEXTPTR(req,xStoreColorsReq); +#endif /* not MUSTCOPY */ + + citem->pixel = def->pixel; + citem->red = def->red; + citem->green = def->green; + citem->blue = def->blue; + citem->flags = def->flags; /* do_red, do_green, do_blue */ + +#ifdef MUSTCOPY + dpy->bufptr -= SIZEOF(xColorItem); /* adjust for GetReqExtra */ + Data (dpy, (char *) citem, len); +#endif /* MUSTCOPY */ + + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} diff --git a/src/StColors.c b/src/StColors.c new file mode 100644 index 00000000..cf970950 --- /dev/null +++ b/src/StColors.c @@ -0,0 +1,62 @@ +/* $Xorg: StColors.c,v 1.4 2001/02/09 02:03:37 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XStoreColors(dpy, cmap, defs, ncolors) +register Display *dpy; +Colormap cmap; +XColor *defs; +int ncolors; +{ + register int i; + xColorItem citem; + register xStoreColorsReq *req; + + LockDisplay(dpy); + GetReq(StoreColors, req); + + req->cmap = cmap; + + req->length += (ncolors * SIZEOF(xColorItem)) >> 2; /* assume size is 4*n */ + + for (i = 0; i < ncolors; i++) { + citem.pixel = defs[i].pixel; + citem.red = defs[i].red; + citem.green = defs[i].green; + citem.blue = defs[i].blue; + citem.flags = defs[i].flags; + + /* note that xColorItem doesn't contain all 16-bit quantities, so + we can't use Data16 */ + Data(dpy, (char *)&citem, (long) SIZEOF(xColorItem)); + /* assume size is 4*n */ + } + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} diff --git a/src/StNColor.c b/src/StNColor.c new file mode 100644 index 00000000..04d27d87 --- /dev/null +++ b/src/StNColor.c @@ -0,0 +1,92 @@ +/* $Xorg: StNColor.c,v 1.4 2001/02/09 02:03:37 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include <stdio.h> +#include "Xlibint.h" +#include "Xcmsint.h" + +extern void _XcmsRGB_to_XColor(); + +#if NeedFunctionPrototypes +XStoreNamedColor( +register Display *dpy, +Colormap cmap, +_Xconst char *name, /* STRING8 */ +unsigned long pixel, /* CARD32 */ +int flags) /* DoRed, DoGreen, DoBlue */ +#else +XStoreNamedColor(dpy, cmap, name, pixel, flags) +register Display *dpy; +Colormap cmap; +char *name; /* STRING8 */ +unsigned long pixel; /* CARD32 */ +int flags; /* DoRed, DoGreen, DoBlue */ +#endif +{ + unsigned int nbytes; + register xStoreNamedColorReq *req; + XcmsCCC ccc; + XcmsColor cmsColor_exact; + XColor scr_def; + + /* + * Let's Attempt to use Xcms approach to Parse Color + */ + if ((ccc = XcmsCCCOfColormap(dpy, cmap)) != (XcmsCCC)NULL) { + if (_XcmsResolveColorString(ccc, &name, &cmsColor_exact, + XcmsRGBFormat) >= XcmsSuccess) { + _XcmsRGB_to_XColor(&cmsColor_exact, &scr_def, 1); + scr_def.pixel = pixel; + scr_def.flags = flags; + return XStoreColor(dpy, cmap, &scr_def); + } + /* + * Otherwise we failed; or name was changed with yet another + * name. Thus pass name to the X Server. + */ + } + + /* + * The Xcms and i18n methods failed, so lets pass it to the server + * for parsing. + */ + + LockDisplay(dpy); + GetReq(StoreNamedColor, req); + + req->cmap = cmap; + req->flags = flags; + req->pixel = pixel; + req->nbytes = nbytes = strlen(name); + req->length += (nbytes + 3) >> 2; /* round up to multiple of 4 */ + Data(dpy, name, (long)nbytes); + UnlockDisplay(dpy); + SyncHandle(); + return 0; +} + + diff --git a/src/StName.c b/src/StName.c new file mode 100644 index 00000000..80fc2dcf --- /dev/null +++ b/src/StName.c @@ -0,0 +1,63 @@ +/* $Xorg: StName.c,v 1.4 2001/02/09 02:03:37 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include <X11/Xlibint.h> +#include <X11/Xatom.h> + +#if NeedFunctionPrototypes +XStoreName ( + register Display *dpy, + Window w, + _Xconst char *name) +#else +XStoreName (dpy, w, name) + register Display *dpy; + Window w; + char *name; +#endif +{ + return XChangeProperty(dpy, w, XA_WM_NAME, XA_STRING, + 8, PropModeReplace, (unsigned char *)name, + name ? strlen(name) : 0); +} + +#if NeedFunctionPrototypes +XSetIconName ( + register Display *dpy, + Window w, + _Xconst char *icon_name) +#else +XSetIconName (dpy, w, icon_name) + register Display *dpy; + Window w; + char *icon_name; +#endif +{ + return XChangeProperty(dpy, w, XA_WM_ICON_NAME, XA_STRING, + 8, PropModeReplace, (unsigned char *)icon_name, + icon_name ? strlen(icon_name) : 0); +} diff --git a/src/StrKeysym.c b/src/StrKeysym.c new file mode 100644 index 00000000..e378f93b --- /dev/null +++ b/src/StrKeysym.c @@ -0,0 +1,148 @@ +/* $Xorg: StrKeysym.c,v 1.5 2001/02/09 02:03:37 xorgcvs Exp $ */ +/* + +Copyright 1985, 1987, 1990, 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. + +*/ + +#include "Xlibint.h" +#include <X11/Xresource.h> +#include <X11/keysymdef.h> +#ifdef X_NOT_STDC_ENV +extern char *getenv(); +#endif + +extern XrmQuark _XrmInternalStringToQuark(); + +#ifdef __STDC__ +#define Const const +#else +#define Const /**/ +#endif + +typedef unsigned long Signature; + +#define NEEDKTABLE +#include "ks_tables.h" + +#ifndef KEYSYMDB +#define KEYSYMDB "/usr/lib/X11/XKeysymDB" +#endif + +static Bool initialized; +static XrmDatabase keysymdb; +static XrmQuark Qkeysym[2]; + +XrmDatabase +_XInitKeysymDB() +{ + if (!initialized) + { + char *dbname; + + XrmInitialize(); + /* use and name of this env var is not part of the standard */ + /* implementation-dependent feature */ + dbname = getenv("XKEYSYMDB"); + if (!dbname) + dbname = KEYSYMDB; + keysymdb = XrmGetFileDatabase(dbname); + if (keysymdb) + Qkeysym[0] = XrmStringToQuark("Keysym"); + initialized = True; + } + return keysymdb; +} + +#if NeedFunctionPrototypes +KeySym XStringToKeysym(s) + _Xconst char *s; +#else +KeySym XStringToKeysym(s) + char *s; +#endif +{ + register int i, n; + int h; + register Signature sig = 0; + register Const char *p = s; + register int c; + register int idx; + Const unsigned char *entry; + unsigned char sig1, sig2; + KeySym val; + + while ((c = *p++)) + sig = (sig << 1) + c; + i = sig % KTABLESIZE; + h = i + 1; + sig1 = (sig >> 8) & 0xff; + sig2 = sig & 0xff; + n = KMAXHASH; + while ((idx = hashString[i])) + { + entry = &_XkeyTable[idx]; + if ((entry[0] == sig1) && (entry[1] == sig2) && + !strcmp(s, (char *)entry + 4)) + { + val = (entry[2] << 8) | entry[3]; + if (!val) + val = XK_VoidSymbol; + return val; + } + if (!--n) + break; + i += h; + if (i >= KTABLESIZE) + i -= KTABLESIZE; + } + + if (!initialized) + (void)_XInitKeysymDB(); + if (keysymdb) + { + XrmValue result; + XrmRepresentation from_type; + char c; + KeySym val; + XrmQuark names[2]; + + names[0] = _XrmInternalStringToQuark(s, p - s - 1, sig, False); + names[1] = NULLQUARK; + (void)XrmQGetResource(keysymdb, names, Qkeysym, &from_type, &result); + if (result.addr && (result.size > 1)) + { + val = 0; + for (i = 0; i < result.size - 1; i++) + { + c = ((char *)result.addr)[i]; + if ('0' <= c && c <= '9') val = (val<<4)+c-'0'; + else if ('a' <= c && c <= 'z') val = (val<<4)+c-'a'+10; + else if ('A' <= c && c <= 'Z') val = (val<<4)+c-'A'+10; + else return NoSymbol; + } + return val; + } + } + return (NoSymbol); +} diff --git a/src/StrToText.c b/src/StrToText.c new file mode 100644 index 00000000..c84c0714 --- /dev/null +++ b/src/StrToText.c @@ -0,0 +1,88 @@ +/* $Xorg: StrToText.c,v 1.4 2001/02/09 02:03:37 xorgcvs Exp $ */ +/* + +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. + +*/ + +#include <X11/Xlibint.h> +#include <X11/Xatom.h> +#include <X11/Xutil.h> + +/* + * XStringListToTextProperty - fill in TextProperty structure with + * concatenated list of null-separated strings. Return True if successful + * else False. Allocate room on end for trailing NULL, but don't include in + * count. + */ + +Status XStringListToTextProperty (argv, argc, textprop) + char **argv; + int argc; + XTextProperty *textprop; +{ + register int i; + register unsigned int nbytes; + XTextProperty proto; + + /* figure out how much space we'll need for this list */ + for (i = 0, nbytes = 0; i < argc; i++) { + nbytes += (unsigned) ((argv[i] ? strlen (argv[i]) : 0) + 1); + } + + /* fill in a prototype containing results so far */ + proto.encoding = XA_STRING; + proto.format = 8; + if (nbytes) + proto.nitems = nbytes - 1; /* subtract one for trailing <NUL> */ + else + proto.nitems = 0; + proto.value = NULL; + + /* build concatenated list of strings */ + if (nbytes > 0) { + register char *buf = Xmalloc (nbytes); + if (!buf) return False; + + proto.value = (unsigned char *) buf; + for (i = 0; i < argc; i++) { + char *arg = argv[i]; + + if (arg) { + (void) strcpy (buf, arg); + buf += (strlen (arg) + 1); + } else { + *buf++ = '\0'; + } + } + } else { + proto.value = (unsigned char *) Xmalloc (1); /* easier for client */ + if (!proto.value) return False; + + proto.value[0] = '\0'; + } + + /* we were successful, so set return value */ + *textprop = proto; + return True; +} diff --git a/src/Sync.c b/src/Sync.c new file mode 100644 index 00000000..98b5463b --- /dev/null +++ b/src/Sync.c @@ -0,0 +1,59 @@ +/* $Xorg: Sync.c,v 1.4 2001/02/09 02:03:37 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#define NEED_REPLIES +#define NEED_EVENTS +#include "Xlibint.h" + +/* Synchronize with errors and events, optionally discarding pending events */ + +XSync (dpy, discard) + register Display *dpy; + Bool discard; +{ + xGetInputFocusReply rep; + register xReq *req; + + LockDisplay(dpy); + GetEmptyReq(GetInputFocus, req); + (void) _XReply (dpy, (xReply *)&rep, 0, xTrue); + + if (discard && dpy->head) { + _XQEvent *qelt; + + for (qelt=dpy->head; qelt; qelt=qelt->next) + qelt->qserial_num = 0; + + ((_XQEvent *)dpy->tail)->next = dpy->qfree; + dpy->qfree = (_XQEvent *)dpy->head; + dpy->head = dpy->tail = NULL; + dpy->qlen = 0; + } + UnlockDisplay(dpy); + return 1; +} + diff --git a/src/Synchro.c b/src/Synchro.c new file mode 100644 index 00000000..9e9d50ad --- /dev/null +++ b/src/Synchro.c @@ -0,0 +1,96 @@ +/* $Xorg: Synchro.c,v 1.4 2001/02/09 02:03:37 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + + +int _XSyncFunction(dpy) +register Display *dpy; +{ + XSync(dpy,0); + return 0; +} + +#if NeedFunctionPrototypes +int (*XSynchronize(Display *dpy, int onoff))() +#else +int (*XSynchronize(dpy,onoff))() + register Display *dpy; + int onoff; +#endif +{ + int (*temp)(); + int (*func)() = NULL; + + if (onoff) + func = _XSyncFunction; + + LockDisplay(dpy); + if (dpy->flags & XlibDisplayPrivSync) { + temp = dpy->savedsynchandler; + dpy->savedsynchandler = func; + } else { + temp = dpy->synchandler; + dpy->synchandler = func; + } + UnlockDisplay(dpy); + return (temp); +} + +#if NeedFunctionPrototypes +int (*XSetAfterFunction( + Display *dpy, + int (*func)( +#if NeedNestedPrototypes + Display* +#endif + ) +))() +#else +int (*XSetAfterFunction(dpy,func))() + register Display *dpy; + int (*func)( +#if NeedNestedPrototypes + Display* +#endif + ); +#endif +{ + int (*temp)(); + + LockDisplay(dpy); + if (dpy->flags & XlibDisplayPrivSync) { + temp = dpy->savedsynchandler; + dpy->savedsynchandler = func; + } else { + temp = dpy->synchandler; + dpy->synchandler = func; + } + UnlockDisplay(dpy); + return (temp); +} + diff --git a/src/Text.c b/src/Text.c new file mode 100644 index 00000000..e8d3df45 --- /dev/null +++ b/src/Text.c @@ -0,0 +1,146 @@ +/* $Xorg: Text.c,v 1.4 2001/02/09 02:03:37 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +#if NeedFunctionPrototypes +XDrawString( + register Display *dpy, + Drawable d, + GC gc, + int x, + int y, + _Xconst char *string, + int length) +#else +XDrawString(dpy, d, gc, x, y, string, length) + register Display *dpy; + Drawable d; + GC gc; + int x, y; + char *string; + int length; +#endif +{ + int Datalength = 0; + register xPolyText8Req *req; + + if (length <= 0) + return 0; + + LockDisplay(dpy); + FlushGC(dpy, gc); + GetReq (PolyText8, req); + req->drawable = d; + req->gc = gc->gid; + req->x = x; + req->y = y; + + + Datalength += SIZEOF(xTextElt) * ((length + 253) / 254) + length; + + + req->length += (Datalength + 3)>>2; /* convert to number of 32-bit words */ + + + /* + * If the entire request does not fit into the remaining space in the + * buffer, flush the buffer first. If the request does fit into the + * empty buffer, then we won't have to flush it at the end to keep + * the buffer 32-bit aligned. + */ + + if (dpy->bufptr + Datalength > dpy->bufmax) + _XFlush (dpy); + + { + int nbytes; + int PartialNChars = length; + /* register xTextElt *elt; */ + char *CharacterOffset = (char *)string; + unsigned char *tbuf; + + while(PartialNChars > 254) + { + nbytes = 254 + SIZEOF(xTextElt); + BufAlloc (unsigned char *, tbuf, nbytes); +/* elt->delta = 0; + * elt->len = 254; + */ + *(unsigned char *)tbuf = 254; + *(tbuf+1) = 0; +/* memcpy ((char *) (elt + 1), CharacterOffset, 254); + */ + memcpy ((char *)tbuf+2, CharacterOffset, 254); + PartialNChars = PartialNChars - 254; + CharacterOffset += 254; + } + + if (PartialNChars) + { + nbytes = PartialNChars + SIZEOF(xTextElt); + BufAlloc (unsigned char *, tbuf, nbytes); +/* elt->delta = 0; + * elt->len = PartialNChars; + */ + *(unsigned char *)tbuf = PartialNChars; + *(tbuf+1) = 0; +/* memcpy ((char *) (elt + 1), CharacterOffset, PartialNChars); + */ + memcpy ((char *)tbuf+2, CharacterOffset, PartialNChars); + } + } + + /* Pad request out to a 32-bit boundary */ + + if (Datalength &= 3) { + char *pad; + /* + * BufAlloc is a macro that uses its last argument more than + * once, otherwise I'd write "BufAlloc (char *, pad, 4-length)" + */ + length = 4 - Datalength; + BufAlloc (char *, pad, length); + /* + * if there are 3 bytes of padding, the first byte MUST be 0 + * so the pad bytes aren't mistaken for a final xTextElt + */ + *pad = 0; + } + + /* + * If the buffer pointer is not now pointing to a 32-bit boundary, + * we must flush the buffer so that it does point to a 32-bit boundary + * at the end of this routine. + */ + + if ((dpy->bufptr - dpy->buffer) & 3) + _XFlush (dpy); + UnlockDisplay(dpy); + SyncHandle(); + return 0; +} diff --git a/src/Text16.c b/src/Text16.c new file mode 100644 index 00000000..f8714459 --- /dev/null +++ b/src/Text16.c @@ -0,0 +1,159 @@ +/* $Xorg: Text16.c,v 1.4 2001/02/09 02:03:37 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +#if NeedFunctionPrototypes +XDrawString16( + register Display *dpy, + Drawable d, + GC gc, + int x, + int y, + _Xconst XChar2b *string, + int length) +#else +XDrawString16(dpy, d, gc, x, y, string, length) + register Display *dpy; + Drawable d; + GC gc; + int x, y; + XChar2b *string; + int length; +#endif +{ + int Datalength = 0; + register xPolyText16Req *req; + + if (length <= 0) + return 0; + + LockDisplay(dpy); + FlushGC(dpy, gc); + GetReq (PolyText16, req); + req->drawable = d; + req->gc = gc->gid; + req->x = x; + req->y = y; + + + Datalength += SIZEOF(xTextElt) * ((length + 253) / 254) + (length << 1); + + + req->length += (Datalength + 3)>>2; /* convert to number of 32-bit words */ + + + /* + * If the entire request does not fit into the remaining space in the + * buffer, flush the buffer first. If the request does fit into the + * empty buffer, then we won't have to flush it at the end to keep + * the buffer 32-bit aligned. + */ + + if (dpy->bufptr + Datalength > dpy->bufmax) + _XFlush (dpy); + + { + int nbytes; + int PartialNChars = length; + register xTextElt *elt; + XChar2b *CharacterOffset = (XChar2b *)string; + + while(PartialNChars > 254) + { + nbytes = 254 * 2 + SIZEOF(xTextElt); + BufAlloc (xTextElt *, elt, nbytes); + elt->delta = 0; + elt->len = 254; +#if defined(MUSTCOPY) || defined(MUSTCOPY2B) + { + register int i; + register unsigned char *cp; + for (i = 0, cp = ((unsigned char *)elt) + 2; i < 254; i++) { + *cp++ = CharacterOffset[i].byte1; + *cp++ = CharacterOffset[i].byte2; + } + } +#else + memcpy ((char *) (elt + 1), (char *)CharacterOffset, 254 * 2); +#endif + PartialNChars = PartialNChars - 254; + CharacterOffset += 254; + } + + if (PartialNChars) + { + nbytes = PartialNChars * 2 + SIZEOF(xTextElt); + BufAlloc (xTextElt *, elt, nbytes); + elt->delta = 0; + elt->len = PartialNChars; +#if defined(MUSTCOPY) || defined(MUSTCOPY2B) + { + register int i; + register unsigned char *cp; + for (i = 0, cp = ((unsigned char *)elt) + 2; i < PartialNChars; + i++) { + *cp++ = CharacterOffset[i].byte1; + *cp++ = CharacterOffset[i].byte2; + } + } +#else + memcpy((char *)(elt + 1), (char *)CharacterOffset, PartialNChars * 2); +#endif + } + } + + /* Pad request out to a 32-bit boundary */ + + if (Datalength &= 3) { + char *pad; + /* + * BufAlloc is a macro that uses its last argument more than + * once, otherwise I'd write "BufAlloc (char *, pad, 4-length)" + */ + length = 4 - Datalength; + BufAlloc (char *, pad, length); + /* + * if there are 3 bytes of padding, the first byte MUST be 0 + * so the pad bytes aren't mistaken for a final xTextElt + */ + *pad = 0; + } + + /* + * If the buffer pointer is not now pointing to a 32-bit boundary, + * we must flush the buffer so that it does point to a 32-bit boundary + * at the end of this routine. + */ + + if ((dpy->bufptr - dpy->buffer) & 3) + _XFlush (dpy); + UnlockDisplay(dpy); + SyncHandle(); + return 0; +} + diff --git a/src/TextExt.c b/src/TextExt.c new file mode 100644 index 00000000..d7f4ff8a --- /dev/null +++ b/src/TextExt.c @@ -0,0 +1,252 @@ +/* $Xorg: TextExt.c,v 1.4 2001/02/09 02:03:37 xorgcvs Exp $ */ +/* + +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. + +*/ +/* + * Copyright 1995 by FUJITSU LIMITED + * This is source code modified by FUJITSU LIMITED under the Joint + * Development Agreement for the CDE/Motif PST. + */ + + +#include "Xlibint.h" + +#define min_byte2 min_char_or_byte2 +#define max_byte2 max_char_or_byte2 + + +/* + * CI_GET_ROWZERO_CHAR_INFO_2D - do the same thing as CI_GET_CHAR_INFO_1D, + * except that the font has more than one row. This is special case of more + * general version used in XTextExt16.c since row == 0. This is used when + * max_byte2 is not zero. A further optimization would do the check for + * min_byte1 being zero ahead of time. + */ + +#define CI_GET_ROWZERO_CHAR_INFO_2D(fs,col,def,cs) \ +{ \ + cs = def; \ + if (fs->min_byte1 == 0 && \ + col >= fs->min_byte2 && col <= fs->max_byte2) { \ + if (fs->per_char == NULL) { \ + cs = &fs->min_bounds; \ + } else { \ + cs = &fs->per_char[(col - fs->min_byte2)]; \ + if (CI_NONEXISTCHAR(cs)) cs = def; \ + } \ + } \ +} + + +/* + * XTextExtents - compute the extents of string given as a sequences of eight + * bit bytes. Since we know that the input characters will always be from the + * first row of the font (i.e. byte1 == 0), we can do some optimizations beyond + * what is done in XTextExtents16. + */ +#if NeedFunctionPrototypes +XTextExtents ( + XFontStruct *fs, + _Xconst char *string, + int nchars, + int *dir, /* RETURN font information */ + int *font_ascent, /* RETURN font information */ + int *font_descent, /* RETURN font information */ + register XCharStruct *overall) /* RETURN character information */ +#else +XTextExtents (fs, string, nchars, dir, font_ascent, font_descent, overall) + XFontStruct *fs; + char *string; + int nchars; + int *dir, *font_ascent, *font_descent; /* RETURN font information */ + register XCharStruct *overall; /* RETURN character information */ +#endif +{ + int i; /* iterator */ + Bool singlerow = (fs->max_byte1 == 0); /* optimization */ + int nfound = 0; /* number of characters found */ + XCharStruct *def; /* info about default char */ + unsigned char *us; /* be 8bit clean */ + + if (singlerow) { /* optimization */ + CI_GET_DEFAULT_INFO_1D (fs, def); + } else { + CI_GET_DEFAULT_INFO_2D (fs, def); + } + + *dir = fs->direction; + *font_ascent = fs->ascent; + *font_descent = fs->descent; + + /* + * Iterate over the input string getting the appropriate * char struct. + * The default (which may be null if there is no def_char) will be returned + * if the character doesn't exist. On the first time * through the loop, + * assign the values to overall; otherwise, compute * the new values. + */ + + for (i = 0, us = (unsigned char *) string; i < nchars; i++, us++) { + register unsigned uc = (unsigned) *us; /* since about to do macro */ + register XCharStruct *cs; + + if (singlerow) { /* optimization */ + CI_GET_CHAR_INFO_1D (fs, uc, def, cs); + } else { + CI_GET_ROWZERO_CHAR_INFO_2D (fs, uc, def, cs); + } + + if (cs) { + if (nfound++ == 0) { + *overall = *cs; + } else { + overall->ascent = max (overall->ascent, cs->ascent); + overall->descent = max (overall->descent, cs->descent); + overall->lbearing = min (overall->lbearing, + overall->width + cs->lbearing); + overall->rbearing = max (overall->rbearing, + overall->width + cs->rbearing); + overall->width += cs->width; + } + } + } + + /* + * if there were no characters, then set everything to 0 + */ + if (nfound == 0) { + overall->width = overall->ascent = overall->descent = + overall->lbearing = overall->rbearing = 0; + } + + return 0; +} + + +/* + * XTextWidth - compute the width of a string of eightbit bytes. This is a + * subset of XTextExtents. + */ +#if NeedFunctionPrototypes +int XTextWidth ( + XFontStruct *fs, + _Xconst char *string, + int count) +#else +int XTextWidth (fs, string, count) + XFontStruct *fs; + char *string; + int count; +#endif +{ + int i; /* iterator */ + Bool singlerow = (fs->max_byte1 == 0); /* optimization */ + XCharStruct *def; /* info about default char */ + unsigned char *us; /* be 8bit clean */ + int width = 0; /* RETURN value */ + + if (singlerow) { /* optimization */ + CI_GET_DEFAULT_INFO_1D (fs, def); + } else { + CI_GET_DEFAULT_INFO_2D (fs, def); + } + + if (def && fs->min_bounds.width == fs->max_bounds.width) + return (fs->min_bounds.width * count); + + /* + * Iterate over all character in the input string; only consider characters + * that exist. + */ + for (i = 0, us = (unsigned char *) string; i < count; i++, us++) { + register unsigned uc = (unsigned) *us; /* since about to do macro */ + register XCharStruct *cs; + + if (singlerow) { /* optimization */ + CI_GET_CHAR_INFO_1D (fs, uc, def, cs); + } else { + CI_GET_ROWZERO_CHAR_INFO_2D (fs, uc, def, cs); + } + + if (cs) width += cs->width; + } + + return width; +} + + + +/* + * _XTextHeight - compute the height of a string of eightbit bytes. + */ +#if NeedFunctionPrototypes +int _XTextHeight ( + XFontStruct *fs, + _Xconst char *string, + int count) +#else +int _XTextHeight (fs, string, count) + XFontStruct *fs; + char *string; + int count; +#endif +{ + int i; /* iterator */ + Bool singlerow = (fs->max_byte1 == 0); /* optimization */ + XCharStruct *def; /* info about default char */ + unsigned char *us; /* be 8bit clean */ + int height = 0; /* RETURN value */ + + if (singlerow) { /* optimization */ + CI_GET_DEFAULT_INFO_1D (fs, def); + } else { + CI_GET_DEFAULT_INFO_2D (fs, def); + } + + if (def && (fs->min_bounds.ascent == fs->max_bounds.ascent) + && (fs->min_bounds.descent == fs->max_bounds.descent)) + return ((fs->min_bounds.ascent + fs->min_bounds.descent) * count); + + /* + * Iterate over all character in the input string; only consider characters + * that exist. + */ + for (i = 0, us = (unsigned char *) string; i < count; i++, us++) { + register unsigned uc = (unsigned) *us; /* since about to do macro */ + register XCharStruct *cs; + + if (singlerow) { /* optimization */ + CI_GET_CHAR_INFO_1D (fs, uc, def, cs); + } else { + CI_GET_ROWZERO_CHAR_INFO_2D (fs, uc, def, cs); + } + + if (cs) height += (cs->ascent + cs->descent); + } + + return height; +} + diff --git a/src/TextExt16.c b/src/TextExt16.c new file mode 100644 index 00000000..24f888ec --- /dev/null +++ b/src/TextExt16.c @@ -0,0 +1,228 @@ +/* $Xorg: TextExt16.c,v 1.4 2001/02/09 02:03:37 xorgcvs Exp $ */ +/* + +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. + +*/ +/* + * Copyright 1995 by FUJITSU LIMITED + * This is source code modified by FUJITSU LIMITED under the Joint + * Development Agreement for the CDE/Motif PST. + */ + + +#include "Xlibint.h" + +#define min_byte2 min_char_or_byte2 +#define max_byte2 max_char_or_byte2 + +/* + * XTextExtents16 - compute the extents of string given as a sequence of + * XChar2bs. + */ +#if NeedFunctionPrototypes +XTextExtents16 ( + XFontStruct *fs, + _Xconst XChar2b *string, + int nchars, + int *dir, /* RETURN font information */ + int *font_ascent, /* RETURN font information */ + int *font_descent, /* RETURN font information */ + register XCharStruct *overall) /* RETURN character information */ +#else +XTextExtents16 (fs, string, nchars, dir, font_ascent, font_descent, overall) + XFontStruct *fs; + XChar2b *string; + int nchars; + int *dir, *font_ascent, *font_descent; /* RETURN font information */ + register XCharStruct *overall; /* RETURN character information */ +#endif +{ + int i; /* iterator */ + Bool singlerow = (fs->max_byte1 == 0); /* optimization */ + int nfound = 0; /* number of characters found */ + XCharStruct *def; /* info about default char */ + + if (singlerow) { + CI_GET_DEFAULT_INFO_1D (fs, def); + } else { + CI_GET_DEFAULT_INFO_2D (fs, def); + } + + *dir = fs->direction; + *font_ascent = fs->ascent; + *font_descent = fs->descent; + + /* + * Iterate over the input string getting the appropriate * char struct. + * The default (which may be null if there is no def_char) will be returned + * if the character doesn't exist. On the first time * through the loop, + * assign the values to overall; otherwise, compute * the new values. + */ + + for (i = 0; i < nchars; i++, string++) { + register XCharStruct *cs; + unsigned int r = (unsigned int) string->byte1; /* watch for macros */ + unsigned int c = (unsigned int) string->byte2; /* watch for macros */ + + if (singlerow) { + unsigned int ind = ((r << 8) | c); /* watch for macros */ + CI_GET_CHAR_INFO_1D (fs, ind, def, cs); + } else { + CI_GET_CHAR_INFO_2D (fs, r, c, def, cs); + } + + if (cs) { + if (nfound++ == 0) { + *overall = *cs; + } else { + overall->ascent = max (overall->ascent, cs->ascent); + overall->descent = max (overall->descent, cs->descent); + overall->lbearing = min (overall->lbearing, + overall->width + cs->lbearing); + overall->rbearing = max (overall->rbearing, + overall->width + cs->rbearing); + overall->width += cs->width; + } + } + } + + /* + * if there were no characters, then set everything to 0 + */ + if (nfound == 0) { + overall->width = overall->ascent = overall->descent = + overall->lbearing = overall->rbearing = 0; + } + + return 0; +} + + +/* + * XTextWidth16 - compute the width of sequence of XChar2bs. This is a + * subset of XTextExtents16. + */ +#if NeedFunctionPrototypes +int XTextWidth16 ( + XFontStruct *fs, + _Xconst XChar2b *string, + int count) +#else +int XTextWidth16 (fs, string, count) + XFontStruct *fs; + XChar2b *string; + int count; +#endif +{ + int i; /* iterator */ + Bool singlerow = (fs->max_byte1 == 0); /* optimization */ + XCharStruct *def; /* info about default char */ + int width = 0; /* RETURN value */ + + if (singlerow) { + CI_GET_DEFAULT_INFO_1D (fs, def); + } else { + CI_GET_DEFAULT_INFO_2D (fs, def); + } + + if (def && fs->min_bounds.width == fs->max_bounds.width) + return (fs->min_bounds.width * count); + + /* + * Iterate over all character in the input string; only consider characters + * that exist. + */ + for (i = 0; i < count; i++, string++) { + register XCharStruct *cs; + unsigned int r = (unsigned int) string->byte1; /* watch for macros */ + unsigned int c = (unsigned int) string->byte2; /* watch for macros */ + + if (singlerow) { + unsigned int ind = ((r << 8) | c); /* watch for macros */ + CI_GET_CHAR_INFO_1D (fs, ind, def, cs); + } else { + CI_GET_CHAR_INFO_2D (fs, r, c, def, cs); + } + + if (cs) width += cs->width; + } + + return width; +} + + +/* + * _XTextHeight16 - compute the height of sequence of XChar2bs. + */ +#if NeedFunctionPrototypes +int _XTextHeight16 ( + XFontStruct *fs, + _Xconst XChar2b *string, + int count) +#else +int _XTextHeight16 (fs, string, count) + XFontStruct *fs; + XChar2b *string; + int count; +#endif +{ + int i; /* iterator */ + Bool singlerow = (fs->max_byte1 == 0); /* optimization */ + XCharStruct *def; /* info about default char */ + int height = 0; /* RETURN value */ + + if (singlerow) { + CI_GET_DEFAULT_INFO_1D (fs, def); + } else { + CI_GET_DEFAULT_INFO_2D (fs, def); + } + + if (def && (fs->min_bounds.ascent == fs->max_bounds.ascent) + && (fs->min_bounds.descent == fs->max_bounds.descent)) + return ((fs->min_bounds.ascent + fs->min_bounds.descent) * count); + + /* + * Iterate over all character in the input string; only consider characters + * that exist. + */ + for (i = 0; i < count; i++, string++) { + register XCharStruct *cs; + unsigned int r = (unsigned int) string->byte1; /* watch for macros */ + unsigned int c = (unsigned int) string->byte2; /* watch for macros */ + + if (singlerow) { + unsigned int ind = ((r << 8) | c); /* watch for macros */ + CI_GET_CHAR_INFO_1D (fs, ind, def, cs); + } else { + CI_GET_CHAR_INFO_2D (fs, r, c, def, cs); + } + + if (cs) height += (cs->ascent + cs->descent); + } + + return height; +} + diff --git a/src/TextToStr.c b/src/TextToStr.c new file mode 100644 index 00000000..2ac934c2 --- /dev/null +++ b/src/TextToStr.c @@ -0,0 +1,115 @@ +/* $Xorg: TextToStr.c,v 1.4 2001/02/09 02:03:37 xorgcvs Exp $ */ +/* + +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. + +*/ + +#include <X11/Xlibint.h> +#include <X11/Xatom.h> +#include <X11/Xutil.h> + + +/* + * XTextPropertyToStringList - set list and count to contain data stored in + * null-separated STRING property. + */ + +Status XTextPropertyToStringList (tp, list_return, count_return) + XTextProperty *tp; + char ***list_return; + int *count_return; +{ + char **list; /* return value */ + int nelements; /* return value */ + register char *cp; /* temp variable */ + char *start; /* start of thing to copy */ + int i, j; /* iterator variables */ + int datalen = (int) tp->nitems; /* for convenience */ + + /* + * make sure we understand how to do it + */ + if (tp->encoding != XA_STRING || tp->format != 8) return False; + + if (datalen == 0) { + *list_return = NULL; + *count_return = 0; + return True; + } + + /* + * walk the list to figure out how many elements there are + */ + nelements = 1; /* since null-separated */ + for (cp = (char *) tp->value, i = datalen; i > 0; cp++, i--) { + if (*cp == '\0') nelements++; + } + + /* + * allocate list and duplicate + */ + list = (char **) Xmalloc (nelements * sizeof (char *)); + if (!list) return False; + + start = (char *) Xmalloc ((datalen + 1) * sizeof (char)); /* for <NUL> */ + if (!start) { + Xfree ((char *) list); + return False; + } + + /* + * copy data + */ + memcpy (start, (char *) tp->value, tp->nitems); + start[datalen] = '\0'; + + /* + * walk down list setting value + */ + for (cp = start, i = datalen + 1, j = 0; i > 0; cp++, i--) { + if (*cp == '\0') { + list[j] = start; + start = (cp + 1); + j++; + } + } + + /* + * append final null pointer and then return data + */ + *list_return = list; + *count_return = nelements; + return True; +} + + +void XFreeStringList (list) + char **list; +{ + if (list) { + if (list[0]) Xfree (list[0]); + Xfree ((char *) list); + } +} + diff --git a/src/TrCoords.c b/src/TrCoords.c new file mode 100644 index 00000000..2363248d --- /dev/null +++ b/src/TrCoords.c @@ -0,0 +1,61 @@ +/* $Xorg: TrCoords.c,v 1.4 2001/02/09 02:03:37 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#define NEED_REPLIES +#include "Xlibint.h" + +Bool XTranslateCoordinates(dpy, src_win, dest_win, src_x, src_y, + dst_x, dst_y, child) + register Display *dpy; + Window src_win, dest_win; + int src_x, src_y; + int *dst_x, *dst_y; + Window *child; +{ + register xTranslateCoordsReq *req; + xTranslateCoordsReply rep; + + LockDisplay(dpy); + GetReq(TranslateCoords, req); + req->srcWid = src_win; + req->dstWid = dest_win; + req->srcX = src_x; + req->srcY = src_y; + if (_XReply (dpy, (xReply *)&rep, 0, xTrue) == 0) { + UnlockDisplay(dpy); + SyncHandle(); + return(False); + } + + *child = rep.child; + *dst_x = cvtINT16toInt (rep.dstX); + *dst_y = cvtINT16toInt (rep.dstY); + UnlockDisplay(dpy); + SyncHandle(); + return ((int)rep.sameScreen); +} + diff --git a/src/UndefCurs.c b/src/UndefCurs.c new file mode 100644 index 00000000..46236ea4 --- /dev/null +++ b/src/UndefCurs.c @@ -0,0 +1,46 @@ +/* $Xorg: UndefCurs.c,v 1.4 2001/02/09 02:03:37 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XUndefineCursor (dpy,w) + register Display *dpy; + Window w; +{ + register xChangeWindowAttributesReq *req; + unsigned long defcurs = None; + + LockDisplay(dpy); + GetReqExtra (ChangeWindowAttributes, 4, req); + req->window = w; + req->valueMask = CWCursor; + OneDataCard32 (dpy, NEXTPTR(req,xChangeWindowAttributesReq), defcurs); + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} + diff --git a/src/UngrabBut.c b/src/UngrabBut.c new file mode 100644 index 00000000..e0e28a3a --- /dev/null +++ b/src/UngrabBut.c @@ -0,0 +1,46 @@ +/* $Xorg: UngrabBut.c,v 1.4 2001/02/09 02:03:37 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XUngrabButton(dpy, button, modifiers, grab_window) +register Display *dpy; +unsigned int button; /* CARD8 */ +unsigned int modifiers; /* CARD16 */ +Window grab_window; +{ + register xUngrabButtonReq *req; + + LockDisplay(dpy); + GetReq(UngrabButton, req); + req->button = button; + req->modifiers = modifiers; + req->grabWindow = grab_window; + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} diff --git a/src/UngrabKbd.c b/src/UngrabKbd.c new file mode 100644 index 00000000..5a9d7562 --- /dev/null +++ b/src/UngrabKbd.c @@ -0,0 +1,42 @@ +/* $Xorg: UngrabKbd.c,v 1.4 2001/02/09 02:03:37 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XUngrabKeyboard (dpy, time) + register Display *dpy; + Time time; +{ + register xResourceReq *req; + + LockDisplay(dpy); + GetResReq(UngrabKeyboard, time, req); + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} + diff --git a/src/UngrabKey.c b/src/UngrabKey.c new file mode 100644 index 00000000..bfd28c0f --- /dev/null +++ b/src/UngrabKey.c @@ -0,0 +1,50 @@ +/* $Xorg: UngrabKey.c,v 1.4 2001/02/09 02:03:37 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XUngrabKey(dpy, key, modifiers, grab_window) + register Display *dpy; + int key; + unsigned int modifiers; + Window grab_window; + +{ + register xUngrabKeyReq *req; + + LockDisplay(dpy); + GetReq(UngrabKey, req); + req->grabWindow = grab_window; + req->modifiers = modifiers; + req->key = key; + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} + + + diff --git a/src/UngrabPtr.c b/src/UngrabPtr.c new file mode 100644 index 00000000..4cf09cf1 --- /dev/null +++ b/src/UngrabPtr.c @@ -0,0 +1,41 @@ +/* $Xorg: UngrabPtr.c,v 1.4 2001/02/09 02:03:37 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XUngrabPointer(dpy, time) +register Display *dpy; +Time time; +{ + register xResourceReq *req; + + LockDisplay(dpy); + GetResReq(UngrabPointer, time, req); + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} diff --git a/src/UngrabSvr.c b/src/UngrabSvr.c new file mode 100644 index 00000000..e5267e18 --- /dev/null +++ b/src/UngrabSvr.c @@ -0,0 +1,41 @@ +/* $Xorg: UngrabSvr.c,v 1.4 2001/02/09 02:03:37 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XUngrabServer (dpy) +register Display *dpy; +{ + register xReq *req; + + LockDisplay(dpy); + GetEmptyReq(UngrabServer, req); + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} + diff --git a/src/UninsCmap.c b/src/UninsCmap.c new file mode 100644 index 00000000..6b06c670 --- /dev/null +++ b/src/UninsCmap.c @@ -0,0 +1,41 @@ +/* $Xorg: UninsCmap.c,v 1.4 2001/02/09 02:03:37 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XUninstallColormap(dpy, cmap) +register Display *dpy; +Colormap cmap; +{ + register xResourceReq *req; + + LockDisplay(dpy); + GetResReq(UninstallColormap, cmap, req); + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} diff --git a/src/UnldFont.c b/src/UnldFont.c new file mode 100644 index 00000000..66f31a96 --- /dev/null +++ b/src/UnldFont.c @@ -0,0 +1,42 @@ + /* $Xorg: UnldFont.c,v 1.4 2001/02/09 02:03:37 xorgcvs Exp $ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XUnloadFont(dpy, font) + register Display *dpy; + Font font; +{ + register xResourceReq *req; + + LockDisplay(dpy); + GetResReq(CloseFont, font, req); + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} + diff --git a/src/UnmapSubs.c b/src/UnmapSubs.c new file mode 100644 index 00000000..bb7158ea --- /dev/null +++ b/src/UnmapSubs.c @@ -0,0 +1,41 @@ +/* $Xorg: UnmapSubs.c,v 1.4 2001/02/09 02:03:37 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XUnmapSubwindows(dpy, win) +register Display *dpy; +Window win; +{ + register xResourceReq *req; + + LockDisplay(dpy); + GetResReq(UnmapSubwindows,win, req); + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} diff --git a/src/UnmapWin.c b/src/UnmapWin.c new file mode 100644 index 00000000..d536ecb0 --- /dev/null +++ b/src/UnmapWin.c @@ -0,0 +1,42 @@ +/* $Xorg: UnmapWin.c,v 1.4 2001/02/09 02:03:37 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XUnmapWindow (dpy, w) + register Display *dpy; + Window w; +{ + register xResourceReq *req; + + LockDisplay(dpy); + GetResReq(UnmapWindow, w, req); + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} + diff --git a/src/VisUtil.c b/src/VisUtil.c new file mode 100644 index 00000000..92cdd93f --- /dev/null +++ b/src/VisUtil.c @@ -0,0 +1,253 @@ +/* $Xorg: VisUtil.c,v 1.4 2001/02/09 02:03:37 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" +#include "Xutil.h" +#include <stdio.h> +/* + * This procedure returns a list of visual information structures + * that match the specified attributes given in the visual information + * template. + * + * If no visuals exist that match the specified attributes, a NULL is + * returned. + * + * The choices for visual_info_mask are: + * + * VisualNoMask + * VisualIDMask + * VisualScreenMask + * VisualDepthMask + * VisualClassMask + * VisualRedMaskMask + * VisualGreenMaskMask + * VisualBlueMaskMask + * VisualColormapSizeMask + * VisualBitsPerRGBMask + * VisualAllMask + */ + +XVisualInfo *XGetVisualInfo( dpy, visual_info_mask, + visual_info_template, nitems) +Display *dpy; +register long visual_info_mask; +register XVisualInfo *visual_info_template; +int *nitems; /* RETURN */ +{ + + register Visual *vp; + register Depth *dp; + Screen *sp; + int ii,screen_s,screen_e,total,count; + register XVisualInfo *vip,*vip_base; + + /* NOTE: NO HIGH PERFORMING CODE TO BE FOUND HERE */ + + LockDisplay(dpy); + + /* ALLOCATE THE ORIGINAL BUFFER; REALLOCED LATER IF OVERFLOW OCCURS; + FREED AT END IF NO VISUALS ARE FOUND */ + + count = 0; + total = 10; + if (! (vip_base = vip = (XVisualInfo *) + Xmalloc((unsigned) (sizeof(XVisualInfo) * total)))) { + UnlockDisplay(dpy); + return (XVisualInfo *) NULL; + } + + /* DETERMINE IF WE DO ALL SCREENS OR ONLY ONE */ + + screen_s = 0; + screen_e = dpy->nscreens; + if (visual_info_mask & VisualScreenMask) + { + screen_s = visual_info_template->screen; + if (screen_s < 0 || screen_s >= screen_e) + screen_e = screen_s; + else + screen_e = screen_s + 1; + } + + /* LOOP THROUGH SCREENS */ + + for (ii=screen_s; ii<screen_e; ii++) + { + sp = (Screen *)(&dpy->screens[ii]); + + /* LOOP THROUGH DEPTHS */ + + for (dp=sp->depths; dp < (sp->depths + sp->ndepths); dp++) + { + if ((visual_info_mask & VisualDepthMask) && + (dp->depth != visual_info_template->depth)) continue; + + /* LOOP THROUGH VISUALS */ + + if (dp->visuals) { + for (vp=dp->visuals; vp<(dp->visuals + dp->nvisuals); vp++) { + if ((visual_info_mask & VisualIDMask) && + (vp->visualid != visual_info_template->visualid)) continue; + if ((visual_info_mask & VisualClassMask) && + (vp->class != visual_info_template->class)) continue; + if ((visual_info_mask & VisualRedMaskMask) && + (vp->red_mask != visual_info_template->red_mask)) continue; + if ((visual_info_mask & VisualGreenMaskMask) && + (vp->green_mask != visual_info_template->green_mask)) continue; + if ((visual_info_mask & VisualBlueMaskMask) && + (vp->blue_mask != visual_info_template->blue_mask)) continue; + if ((visual_info_mask & VisualColormapSizeMask) && + (vp->map_entries != visual_info_template->colormap_size)) continue; + if ((visual_info_mask & VisualBitsPerRGBMask) && + (vp->bits_per_rgb != visual_info_template->bits_per_rgb)) continue; + + /* YEA!!! WE FOUND A GOOD ONE */ + + if (count+1 > total) + { + XVisualInfo *old_vip_base = vip_base; + total += 10; + if (! (vip_base = (XVisualInfo *) + Xrealloc((char *) vip_base, + (unsigned) (sizeof(XVisualInfo) * total)))) { + Xfree((char *) old_vip_base); + UnlockDisplay(dpy); + return (XVisualInfo *) NULL; + } + vip = &vip_base[count]; + } + + count++; + + vip->visual = _XVIDtoVisual(dpy, vp->visualid); + vip->visualid = vp->visualid; + vip->screen = ii; + vip->depth = dp->depth; + vip->class = vp->class; + vip->red_mask = vp->red_mask; + vip->green_mask = vp->green_mask; + vip->blue_mask = vp->blue_mask; + vip->colormap_size = vp->map_entries; + vip->bits_per_rgb = vp->bits_per_rgb; + + vip++; + + } /* END OF LOOP ON VISUALS */ + } /* END OF IF THERE ARE ANY VISUALS AT THIS DEPTH */ + + } /* END OF LOOP ON DEPTHS */ + + } /* END OF LOOP ON SCREENS */ + + UnlockDisplay(dpy); + + if (count) + { + *nitems = count; + return vip_base; + } + + Xfree((char *) vip_base); + *nitems = 0; + return NULL; +} + + +/* + * This procedure will return the visual information for a visual + * that matches the specified depth and class for a screen. Since + * multiple visuals may exist that match the specified depth and + * class, which visual chosen is undefined. + * + * If a visual is found, True is returned as the function value, + * otherwise False is returned. + */ + +Status XMatchVisualInfo( dpy, screen, depth, class, visual_info) + Display *dpy; + int screen; + int depth; + int class; + XVisualInfo *visual_info; /* RETURNED */ +{ + + Visual *vp; + Depth *dp; + Screen *sp; + int ii,jj; + + if (screen < 0 || screen >= dpy->nscreens) + return False; + + LockDisplay(dpy); + + sp = (Screen *)(&dpy->screens[screen]); + + dp = sp->depths; + + for (ii=0; ii < sp->ndepths; ii++) + { + + /* LOOK THROUGH DEPTHS FOR THE WANTED DEPTH */ + + if (dp->depth == depth) + { + vp = dp->visuals; + + /* LOOK THROUGH VISUALS FOR THE WANTED CLASS */ + + /* if nvisuals == 0 then vp will be NULL */ + for (jj=0; jj<dp->nvisuals; jj++) + { + if (vp->class == class) + { + visual_info->visual = _XVIDtoVisual(dpy, vp->visualid); + visual_info->visualid = vp->visualid; + visual_info->screen = screen; + visual_info->depth = depth; + visual_info->class = vp->class; + visual_info->red_mask = vp->red_mask; + visual_info->green_mask = vp->green_mask; + visual_info->blue_mask = vp->blue_mask; + visual_info->colormap_size = vp->map_entries; + visual_info->bits_per_rgb = vp->bits_per_rgb; + UnlockDisplay(dpy); + return True; + } + vp++; + } + } + + dp++; + + } + + UnlockDisplay(dpy); + + return False; + +} diff --git a/src/WMGeom.c b/src/WMGeom.c new file mode 100644 index 00000000..96b9b536 --- /dev/null +++ b/src/WMGeom.c @@ -0,0 +1,195 @@ +/* $Xorg: WMGeom.c,v 1.4 2001/02/09 02:03:37 xorgcvs Exp $ */ +/* + +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. + +*/ + +#include "Xlibint.h" +#include "Xutil.h" + +static int _GeometryMaskToGravity(); + + +/* + * This routine given a user supplied positional argument and a default + * argument (fully qualified) will return the position the window should take + * as well as the gravity to be set in the WM_NORMAL_HINTS size hints. + * Always sets all return values and returns a mask describing which fields + * were set by the user or'ed with whether or not the x and y values should + * be considered "negative". + */ + +#if NeedFunctionPrototypes +int XWMGeometry ( + Display *dpy, /* user's display connection */ + int screen, /* screen on which to do computation */ + _Xconst char *user_geom, /* user provided geometry spec */ + _Xconst char *def_geom, /* default geometry spec for window */ + unsigned int bwidth, /* border width */ + XSizeHints *hints, /* usually WM_NORMAL_HINTS */ + int *x_return, /* location of window */ + int *y_return, /* location of window */ + int *width_return, /* size of window */ + int *height_return, /* size of window */ + int *gravity_return) /* gravity of window */ +#else +int XWMGeometry (dpy, screen, user_geom, def_geom, bwidth, hints, + x_return, y_return, width_return, height_return, + gravity_return) + Display *dpy; /* user's display connection */ + int screen; /* screen on which to do computation */ + char *user_geom; /* user provided geometry spec */ + char *def_geom; /* default geometry spec for window */ + unsigned int bwidth; /* border width */ + XSizeHints *hints; /* usually WM_NORMAL_HINTS */ + int *x_return, *y_return; /* location of window */ + int *width_return, *height_return; /* size of window */ + int *gravity_return; /* gravity of window */ +#endif +{ + int ux, uy; /* returned values from parse */ + unsigned int uwidth, uheight; /* returned values from parse */ + int umask; /* parse mask of returned values */ + int dx, dy; /* default values from parse */ + unsigned int dwidth, dheight; /* default values from parse */ + int dmask; /* parse mask of returned values */ + int base_width, base_height; /* valid amounts */ + int min_width, min_height; /* valid amounts */ + int width_inc, height_inc; /* valid amounts */ + int rx, ry, rwidth, rheight; /* return values */ + int rmask; /* return mask */ + + /* + * Get the base sizes and increments. Section 4.1.2.3 of the ICCCM + * states that the base and minimum sizes are defaults for each other. + * If neither is given, then the base sizes should be 0. These parameters + * control the sets of sizes that window managers should allow for the + * window according to the following formulae: + * + * width = base_width + (i * width_inc) + * height = base_height + (j * height_inc) + */ + base_width = ((hints->flags & PBaseSize) ? hints->base_width : + ((hints->flags & PMinSize) ? hints->min_width : 0)); + base_height = ((hints->flags & PBaseSize) ? hints->base_height : + ((hints->flags & PMinSize) ? hints->min_height : 0)); + min_width = ((hints->flags & PMinSize) ? hints->min_width : base_width); + min_height = ((hints->flags & PMinSize) ? hints->min_height : base_height); + width_inc = (hints->flags & PResizeInc) ? hints->width_inc : 1; + height_inc = (hints->flags & PResizeInc) ? hints->height_inc : 1; + + + /* + * parse the two geometry masks + */ + rmask = umask = XParseGeometry (user_geom, &ux, &uy, &uwidth, &uheight); + dmask = XParseGeometry (def_geom, &dx, &dy, &dwidth, &dheight); + + + /* + * get the width and height: + * 1. if user-specified, then take that value + * 2. else, if program-specified, then take that value + * 3. else, take 1 + * 4. multiply by the size increment + * 5. and add to the base size + */ + rwidth = ((((umask & WidthValue) ? uwidth : + ((dmask & WidthValue) ? dwidth : 1)) * width_inc) + + base_width); + rheight = ((((umask & HeightValue) ? uheight : + ((dmask & HeightValue) ? dheight : 1)) * height_inc) + + base_height); + + /* + * Make sure computed size is within limits. Note that we always do the + * lower bounds check since the base size (which defaults to 0) should + * be used if a minimum size isn't specified. + */ + if (rwidth < min_width) rwidth = min_width; + if (rheight < min_height) rheight = min_height; + + if (hints->flags & PMaxSize) { + if (rwidth > hints->max_width) rwidth = hints->max_width; + if (rheight > hints->max_height) rheight = hints->max_height; + } + + + /* + * Compute the location. Set the negative flags in the return mask + * (and watch out for borders), if necessary. + */ + if (umask & XValue) { + rx = ((umask & XNegative) ? + (DisplayWidth (dpy, screen) + ux - rwidth - 2 * bwidth) : ux); + } else if (dmask & XValue) { + if (dmask & XNegative) { + rx = (DisplayWidth (dpy, screen) + dx - rwidth - 2 * bwidth); + rmask |= XNegative; + } else + rx = dx; + } else { + rx = 0; /* gotta choose something... */ + } + + if (umask & YValue) { + ry = ((umask & YNegative) ? + (DisplayHeight(dpy, screen) + uy - rheight - 2 * bwidth) : uy); + } else if (dmask & YValue) { + if (dmask & YNegative) { + ry = (DisplayHeight(dpy, screen) + dy - rheight - 2 * bwidth); + rmask |= YNegative; + } else + ry = dy; + } else { + ry = 0; /* gotta choose something... */ + } + + + /* + * All finished, so set the return variables. + */ + *x_return = rx; + *y_return = ry; + *width_return = rwidth; + *height_return = rheight; + *gravity_return = _GeometryMaskToGravity (rmask); + return rmask; +} + + +static int _GeometryMaskToGravity (mask) + int mask; +{ + switch (mask & (XNegative|YNegative)) { + case 0: + return NorthWestGravity; + case XNegative: + return NorthEastGravity; + case YNegative: + return SouthWestGravity; + default: + return SouthEastGravity; + } +} diff --git a/src/WMProps.c b/src/WMProps.c new file mode 100644 index 00000000..c1ed9a9d --- /dev/null +++ b/src/WMProps.c @@ -0,0 +1,132 @@ +/* $Xorg: WMProps.c,v 1.4 2001/02/09 02:03:37 xorgcvs Exp $ */ +/* + +Copyright 1987, 1988, 1993, 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 1988 by Wyse Technology, Inc., San Jose, Ca., +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 Wyse not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +WYSE 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. + +******************************************************************/ + +#include <X11/Xlibint.h> +#include <X11/Xatom.h> +#include <X11/Xutil.h> +#include <X11/Xos.h> + +#ifdef X_NOT_STDC_ENV +extern char *getenv(); +#endif + +/* + * XSetWMProperties sets the following properties: + * WM_NAME type: TEXT format: varies? + * WM_ICON_NAME type: TEXT format: varies? + * WM_HINTS type: WM_HINTS format: 32 + * WM_COMMAND type: TEXT format: varies? + * WM_CLIENT_MACHINE type: TEXT format: varies? + * WM_NORMAL_HINTS type: WM_SIZE_HINTS format: 32 + * WM_CLASS type: STRING/STRING format: 8 + */ + +void XSetWMProperties (dpy, w, windowName, iconName, argv, argc, sizeHints, + wmHints, classHints) + Display *dpy; + Window w; /* window to decorate */ + XTextProperty *windowName; /* name of application */ + XTextProperty *iconName; /* name string for icon */ + char **argv; /* command line */ + int argc; /* size of command line */ + XSizeHints *sizeHints; /* size hints for window in its normal state */ + XWMHints *wmHints; /* miscelaneous window manager hints */ + XClassHint *classHints; /* resource name and class */ +{ + XTextProperty textprop; + char hostName[256]; + int len = _XGetHostname (hostName, sizeof hostName); + + /* set names of window and icon */ + if (windowName) XSetWMName (dpy, w, windowName); + if (iconName) XSetWMIconName (dpy, w, iconName); + + /* set the command if given */ + if (argv) { + /* + * for UNIX and other operating systems which use nul-terminated + * arrays of STRINGs. + */ + XSetCommand (dpy, w, argv, argc); + } + + /* set the name of the machine on which this application is running */ + textprop.value = (unsigned char *) hostName; + textprop.encoding = XA_STRING; + textprop.format = 8; + textprop.nitems = len; + XSetWMClientMachine (dpy, w, &textprop); + + /* set hints about how geometry and window manager interaction */ + if (sizeHints) XSetWMNormalHints (dpy, w, sizeHints); + if (wmHints) XSetWMHints (dpy, w, wmHints); + if (classHints) { + XClassHint tmp; + + if (!classHints->res_name) { + tmp.res_name = getenv ("RESOURCE_NAME"); + if (!tmp.res_name && argv && argv[0]) { + /* + * UNIX uses /dir/subdir/.../basename; other operating + * systems will have to change this. + */ + char *cp = strrchr (argv[0], '/'); + tmp.res_name = (cp ? cp + 1 : argv[0]); + } + tmp.res_class = classHints->res_class; + classHints = &tmp; + } + XSetClassHint (dpy, w, classHints); + } +} + diff --git a/src/WarpPtr.c b/src/WarpPtr.c new file mode 100644 index 00000000..e3dfc8da --- /dev/null +++ b/src/WarpPtr.c @@ -0,0 +1,54 @@ +/* $Xorg: WarpPtr.c,v 1.4 2001/02/09 02:03:37 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +XWarpPointer(dpy, src_win, dest_win, src_x, src_y, src_width, src_height, + dest_x, dest_y) + register Display *dpy; + Window src_win, dest_win; + int src_x, src_y; + unsigned int src_width, src_height; + int dest_x, dest_y; +{ + register xWarpPointerReq *req; + + LockDisplay(dpy); + GetReq(WarpPointer, req); + req->srcWid = src_win; + req->dstWid = dest_win; + req->srcX = src_x; + req->srcY = src_y; + req->srcWidth = src_width; + req->srcHeight = src_height; + req->dstX = dest_x; + req->dstY = dest_y; + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} + diff --git a/src/WinEvent.c b/src/WinEvent.c new file mode 100644 index 00000000..726c7729 --- /dev/null +++ b/src/WinEvent.c @@ -0,0 +1,84 @@ +/* $Xorg: WinEvent.c,v 1.4 2001/02/09 02:03:37 xorgcvs Exp $ */ +/* + +Copyright 1985, 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. + +*/ + +#define NEED_EVENTS +#include "Xlibint.h" + +#ifdef __STDC__ +#define Const const +#else +#define Const /**/ +#endif + +extern long Const _Xevent_to_mask[]; +#define AllPointers (PointerMotionMask|PointerMotionHintMask|ButtonMotionMask) +#define AllButtons (Button1MotionMask|Button2MotionMask|Button3MotionMask|\ + Button4MotionMask|Button5MotionMask) + +/* + * Return the next event in the queue + * for the given window matching one of the events in the mask. + * Events earlier in the queue are not discarded. + * If none found, flush, and then wait until an event arrives which + * matches. + */ + +XWindowEvent (dpy, w, mask, event) + register Display *dpy; + Window w; /* Selected window. */ + long mask; /* Selected event mask. */ + register XEvent *event; /* XEvent to be filled in. */ +{ + register _XQEvent *prev, *qelt; + unsigned long qe_serial; + + LockDisplay(dpy); + prev = NULL; + while (1) { + for (qelt = prev ? prev->next : dpy->head; + qelt; + prev = qelt, qelt = qelt->next) { + if ((qelt->event.xany.window == w) && + (qelt->event.type < LASTEvent) && + (_Xevent_to_mask[qelt->event.type] & mask) && + ((qelt->event.type != MotionNotify) || + (mask & AllPointers) || + (mask & AllButtons & qelt->event.xmotion.state))) { + *event = qelt->event; + _XDeq(dpy, prev, qelt); + UnlockDisplay(dpy); + return 0; + } + } + if (prev) + qe_serial = prev->qserial_num; + _XReadEvents(dpy); + if (prev && prev->qserial_num != qe_serial) + /* another thread has snatched this event */ + prev = NULL; + } +} diff --git a/src/Window.c b/src/Window.c new file mode 100644 index 00000000..5d1f0afe --- /dev/null +++ b/src/Window.c @@ -0,0 +1,136 @@ +/* $Xorg: Window.c,v 1.5 2001/02/09 02:03:37 xorgcvs Exp $ */ +/* + +Copyright 1986, 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. + +*/ + +#include "Xlibint.h" + +void _XProcessWindowAttributes (dpy, req, valuemask, attributes) + register Display *dpy; + xChangeWindowAttributesReq *req; + register unsigned long valuemask; + register XSetWindowAttributes *attributes; +{ + unsigned long values[32]; + register unsigned long *value = values; + unsigned int nvalues; + + if (valuemask & CWBackPixmap) + *value++ = attributes->background_pixmap; + + if (valuemask & CWBackPixel) + *value++ = attributes->background_pixel; + + if (valuemask & CWBorderPixmap) + *value++ = attributes->border_pixmap; + + if (valuemask & CWBorderPixel) + *value++ = attributes->border_pixel; + + if (valuemask & CWBitGravity) + *value++ = attributes->bit_gravity; + + if (valuemask & CWWinGravity) + *value++ = attributes->win_gravity; + + if (valuemask & CWBackingStore) + *value++ = attributes->backing_store; + + if (valuemask & CWBackingPlanes) + *value++ = attributes->backing_planes; + + if (valuemask & CWBackingPixel) + *value++ = attributes->backing_pixel; + + if (valuemask & CWOverrideRedirect) + *value++ = attributes->override_redirect; + + if (valuemask & CWSaveUnder) + *value++ = attributes->save_under; + + if (valuemask & CWEventMask) + *value++ = attributes->event_mask; + + if (valuemask & CWDontPropagate) + *value++ = attributes->do_not_propagate_mask; + + if (valuemask & CWColormap) + *value++ = attributes->colormap; + + if (valuemask & CWCursor) + *value++ = attributes->cursor; + + req->length += (nvalues = value - values); + + nvalues <<= 2; /* watch out for macros... */ + Data32 (dpy, (long *) values, (long)nvalues); + +} + +#define AllMaskBits (CWBackPixmap|CWBackPixel|CWBorderPixmap|\ + CWBorderPixel|CWBitGravity|CWWinGravity|\ + CWBackingStore|CWBackingPlanes|CWBackingPixel|\ + CWOverrideRedirect|CWSaveUnder|CWEventMask|\ + CWDontPropagate|CWColormap|CWCursor) + +Window XCreateWindow(dpy, parent, x, y, width, height, + borderWidth, depth, class, visual, valuemask, attributes) + register Display *dpy; + Window parent; + int x, y; + unsigned int width, height, borderWidth; + int depth; + unsigned int class; + Visual *visual; + unsigned long valuemask; + XSetWindowAttributes *attributes; +{ + Window wid; + register xCreateWindowReq *req; + + LockDisplay(dpy); + GetReq(CreateWindow, req); + req->parent = parent; + req->x = x; + req->y = y; + req->width = width; + req->height = height; + req->borderWidth = borderWidth; + req->depth = depth; + req->class = class; + if (visual == CopyFromParent) + req->visual = CopyFromParent; + else + req->visual = visual->visualid; + wid = req->wid = XAllocID(dpy); + valuemask &= AllMaskBits; + if ((req->mask = valuemask)) + _XProcessWindowAttributes (dpy, (xChangeWindowAttributesReq *)req, + valuemask, attributes); + UnlockDisplay(dpy); + SyncHandle(); + return (wid); + } + diff --git a/src/Withdraw.c b/src/Withdraw.c new file mode 100644 index 00000000..e9735a9b --- /dev/null +++ b/src/Withdraw.c @@ -0,0 +1,81 @@ +/* $Xorg: Withdraw.c,v 1.4 2001/02/09 02:03:37 xorgcvs Exp $ */ + +/*********************************************************** +Copyright 1988 by Wyse Technology, Inc., San Jose, Ca., + + 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 Wyse not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +WYSE 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. + +******************************************************************/ +/* + +Copyright 1988, 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. + +*/ + +#define NEED_EVENTS +#include <X11/Xlibint.h> +#include <X11/Xatom.h> +#include <X11/Xos.h> +#include <X11/Xutil.h> +#include <stdio.h> + +/* + * This function instructs the window manager to change this window from + * NormalState or IconicState to Withdrawn. + */ +Status XWithdrawWindow (dpy, w, screen) + Display *dpy; + Window w; + int screen; +{ + XUnmapEvent ev; + Window root = RootWindow (dpy, screen); + + XUnmapWindow (dpy, w); + + ev.type = UnmapNotify; + ev.event = root; + ev.window = w; + ev.from_configure = False; + return (XSendEvent (dpy, root, False, + SubstructureRedirectMask|SubstructureNotifyMask, + (XEvent *)&ev)); +} diff --git a/src/WrBitF.c b/src/WrBitF.c new file mode 100644 index 00000000..e8fad11d --- /dev/null +++ b/src/WrBitF.c @@ -0,0 +1,159 @@ +/* $Xorg: WrBitF.c,v 1.4 2001/02/09 02:03:37 xorgcvs Exp $ */ +/* + +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. + +*/ + +#include "Xlibint.h" +#include <X11/Xos.h> +#include "Xutil.h" +#include <stdio.h> + +#define ERR_RETURN 0 + +static char *Format_Image(image, resultsize) +XImage *image; +int *resultsize; +{ + register int x, c, b; + register char *ptr; + int y; + char *data; + int width, height; + int bytes_per_line; + + width = image->width; + height = image->height; + + bytes_per_line = (width+7)/8; + *resultsize = bytes_per_line * height; /* Calculate size of data */ + + data = (char *) Xmalloc( *resultsize ); /* Get space for data */ + if (!data) + return(ERR_RETURN); + + /* + * The slow but robust brute force method of converting the image: + */ + ptr = data; + c = 0; b=1; + for (y=0; y<height; y++) { + for (x=0; x<width;) { + if (XGetPixel(image, x, y)) + c |= b; + b <<= 1; + if (!(++x & 7)) { + *(ptr++)=c; + c=0; b=1; + } + } + if (x & 7) { + *(ptr++)=c; + c=0; b=1; + } + } + + return(data); +} + +#define BYTES_PER_OUTPUT_LINE 12 + +#if NeedFunctionPrototypes +int XWriteBitmapFile( + Display *display, + _Xconst char *filename, + Pixmap bitmap, + unsigned int width, + unsigned int height, + int x_hot, + int y_hot) +#else +int XWriteBitmapFile(display, filename, bitmap, width, height, x_hot, y_hot) + Display *display; + char *filename; + Pixmap bitmap; + unsigned int width, height; + int x_hot, y_hot; +#endif +{ + char *data, *ptr; + int size, byte; + int c; + XImage *image; + FILE *stream; + char *name; + + if (!(name = strrchr(filename, '/'))) + name = (char *)filename; + else + name++; + + if (!(stream = fopen(filename, "w"))) + return(BitmapOpenFailed); + + /* Convert bitmap to an image */ + image = XGetImage(display, bitmap, 0,0,width, height, 1L, XYPixmap); + if (!image) { + fclose(stream); + return(4); /* XXX spec does not say what to return */ + } + + /* Get standard format for data */ + data = Format_Image(image, &size); + XDestroyImage(image); + if (!data) { + fclose(stream); + return(BitmapNoMemory); + } + + /* Write out standard header */ + fprintf(stream, "#define %s_width %d\n", name, width); + fprintf(stream, "#define %s_height %d\n", name, height); + if (x_hot != -1) { + fprintf(stream, "#define %s_x_hot %d\n", name, x_hot); + fprintf(stream, "#define %s_y_hot %d\n", name, y_hot); + } + + /* Print out the data itself */ + fprintf(stream, "static unsigned char %s_bits[] = {", name); + for (byte=0, ptr=data; byte<size; byte++, ptr++) { + if (!byte) + fprintf(stream, "\n "); + else if (!(byte % BYTES_PER_OUTPUT_LINE)) + fprintf(stream, ",\n "); + else + fprintf(stream, ", "); + c = *ptr; + if (c<0) + c += 256; + fprintf(stream, "0x%02x", c); + } + fprintf(stream, "};\n"); + + Xfree(data); + fclose(stream); + return(BitmapSuccess); +} diff --git a/src/XErrorDB b/src/XErrorDB new file mode 100644 index 00000000..5996026c --- /dev/null +++ b/src/XErrorDB @@ -0,0 +1,737 @@ +! $Xorg: XErrorDB,v 1.3 2000/08/17 19:44:59 cpqbld Exp $ +! Copyright 1993, 1995, 1998 The Open Group + +! All Rights Reserved. +! +! 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. +! +! these are used in XGetErrorMessage. +XlibMessage.XError: X Error of failed request +XlibMessage.MajorCode: Major opcode of failed request: %d +XlibMessage.MinorCode: Minor opcode of failed request: %d +XlibMessage.ResourceID: Resource id in failed request: 0x%lx +XlibMessage.Value: Value in failed request: 0x%lx +XlibMessage.AtomID: Atom id in failed request: 0x%lx +XlibMessage.ErrorSerial: Serial number of failed request: %lu +XlibMessage.CurrentSerial: Current serial number in output stream: %lu +! X request codes. +XRequest.1:X_CreateWindow +XRequest.2:X_ChangeWindowAttributes +XRequest.3:X_GetWindowAttributes +XRequest.4:X_DestroyWindow +XRequest.5:X_DestroySubwindows +XRequest.6:X_ChangeSaveSet +XRequest.7:X_ReparentWindow +XRequest.8:X_MapWindow +XRequest.9:X_MapSubwindows +XRequest.10:X_UnmapWindow +XRequest.11:X_UnmapSubwindows +XRequest.12:X_ConfigureWindow +XRequest.13:X_CirculateWindow +XRequest.14:X_GetGeometry +XRequest.15:X_QueryTree +XRequest.16:X_InternAtom +XRequest.17:X_GetAtomName +XRequest.18:X_ChangeProperty +XRequest.19:X_DeleteProperty +XRequest.20:X_GetProperty +XRequest.21:X_ListProperties +XRequest.22:X_SetSelectionOwner +XRequest.23:X_GetSelectionOwner +XRequest.24:X_ConvertSelection +XRequest.25:X_SendEvent +XRequest.26:X_GrabPointer +XRequest.27:X_UngrabPointer +XRequest.28:X_GrabButton +XRequest.29:X_UngrabButton +XRequest.30:X_ChangeActivePointerGrab +XRequest.31:X_GrabKeyboard +XRequest.32:X_UngrabKeyboard +XRequest.33:X_GrabKey +XRequest.34:X_UngrabKey +XRequest.35:X_AllowEvents +XRequest.36:X_GrabServer +XRequest.37:X_UngrabServer +XRequest.38:X_QueryPointer +XRequest.39:X_GetMotionEvents +XRequest.40:X_TranslateCoords +XRequest.41:X_WarpPointer +XRequest.42:X_SetInputFocus +XRequest.43:X_GetInputFocus +XRequest.44:X_QueryKeymap +XRequest.45:X_OpenFont +XRequest.46:X_CloseFont +XRequest.47:X_QueryFont +XRequest.48:X_QueryTextExtents +XRequest.49:X_ListFonts +XRequest.50:X_ListFontsWithInfo +XRequest.51:X_SetFontPath +XRequest.52:X_GetFontPath +XRequest.53:X_CreatePixmap +XRequest.54:X_FreePixmap +XRequest.55:X_CreateGC +XRequest.56:X_ChangeGC +XRequest.57:X_CopyGC +XRequest.58:X_SetDashes +XRequest.59:X_SetClipRectangles +XRequest.60:X_FreeGC +XRequest.61:X_ClearArea +XRequest.62:X_CopyArea +XRequest.63:X_CopyPlane +XRequest.64:X_PolyPoint +XRequest.65:X_PolyLine +XRequest.66:X_PolySegment +XRequest.67:X_PolyRectangle +XRequest.68:X_PolyArc +XRequest.69:X_FillPoly +XRequest.70:X_PolyFillRectangle +XRequest.71:X_PolyFillArc +XRequest.72:X_PutImage +XRequest.73:X_GetImage +XRequest.74:X_PolyText8 +XRequest.75:X_PolyText16 +XRequest.76:X_ImageText8 +XRequest.77:X_ImageText16 +XRequest.78:X_CreateColormap +XRequest.79:X_FreeColormap +XRequest.80:X_CopyColormapAndFree +XRequest.81:X_InstallColormap +XRequest.82:X_UninstallColormap +XRequest.83:X_ListInstalledColormaps +XRequest.84:X_AllocColor +XRequest.85:X_AllocNamedColor +XRequest.86:X_AllocColorCells +XRequest.87:X_AllocColorPlanes +XRequest.88:X_FreeColors +XRequest.89:X_StoreColors +XRequest.90:X_StoreNamedColor +XRequest.91:X_QueryColors +XRequest.92:X_LookupColor +XRequest.93:X_CreateCursor +XRequest.94:X_CreateGlyphCursor +XRequest.95:X_FreeCursor +XRequest.96:X_RecolorCursor +XRequest.97:X_QueryBestSize +XRequest.98:X_QueryExtension +XRequest.99:X_ListExtensions +XRequest.100:X_ChangeKeyboardMapping +XRequest.101:X_GetKeyboardMapping +XRequest.102:X_ChangeKeyboardControl +XRequest.103:X_GetKeyboardControl +XRequest.104:X_Bell +XRequest.105:X_ChangePointerControl +XRequest.106:X_GetPointerControl +XRequest.107:X_SetScreenSaver +XRequest.108:X_GetScreenSaver +XRequest.109:X_ChangeHosts +XRequest.110:X_ListHosts +XRequest.111:X_SetAccessControl +XRequest.112:X_SetCloseDownMode +XRequest.113:X_KillClient +XRequest.114:X_RotateProperties +XRequest.115:X_ForceScreenSaver +XRequest.116:X_SetPointerMapping +XRequest.117:X_GetPointerMapping +XRequest.118:X_SetModifierMapping +XRequest.119:X_GetModifierMapping +XRequest.127:X_NoOperation +! X Error Codes +XProtoError.0: unknown error code 0 +XProtoError.1: BadRequest (invalid request code or no such operation) +XProtoError.2: BadValue (integer parameter out of range for operation) +XProtoError.3: BadWindow (invalid Window parameter) +XProtoError.4: BadPixmap (invalid Pixmap parameter) +XProtoError.5: BadAtom (invalid Atom parameter) +XProtoError.6: BadCursor (invalid Cursor parameter) +XProtoError.7: BadFont (invalid Font parameter) +XProtoError.8: BadMatch (invalid parameter attributes) +XProtoError.9: BadDrawable (invalid Pixmap or Window parameter) +XProtoError.10: BadAccess (attempt to access private resource denied) +XProtoError.11: BadAlloc (insufficient resources for operation) +XProtoError.12: BadColor (invalid Colormap parameter) +XProtoError.13: BadGC (invalid GC parameter) +XProtoError.14: BadIDChoice (invalid resource ID chosen for this connection) +XProtoError.15: BadName (named color or font does not exist) +XProtoError.16: BadLength (poly request too large or internal Xlib length error) +XProtoError.17: BadImplementation (server does not implement operation) +! Multi-Buffering extension, not an X Consortium standard +XRequest.Multi-Buffering.0: X_MbufGetBufferVersion +XRequest.Multi-Buffering.1: X_MbufCreateImageBuffers +XRequest.Multi-Buffering.2: X_MbufDestroyImageBuffers +XRequest.Multi-Buffering.3: X_MbufDisplayImageBuffers +XRequest.Multi-Buffering.4: X_MbufSetMultiBufferAttributes +XRequest.Multi-Buffering.5: X_MbufGetMultiBufferAttributes +XRequest.Multi-Buffering.6: X_MbufSetBufferAttributes +XRequest.Multi-Buffering.7: X_MbufGetBufferAttributes +XRequest.Multi-Buffering.8: X_MbufGetBufferInfo +XRequest.Multi-Buffering.9: X_MbufCreateStereoWindow +XProtoError.Multi-Buffering.0: BadBuffer (invalid Buffer parameter) +XlibMessage.Multi-Buffering.0: Buffer id in failed request: 0x%lx +! SHAPE extension, an X Consortium standard +XRequest.SHAPE.0: X_ShapeQueryVersion +XRequest.SHAPE.1: X_ShapeRectangles +XRequest.SHAPE.2: X_ShapeMask +XRequest.SHAPE.3: X_ShapeCombine +XRequest.SHAPE.4: X_ShapeOffset +XRequest.SHAPE.5: X_ShapeQueryExtents +XRequest.SHAPE.6: X_ShapeSelectInput +XRequest.SHAPE.7: X_ShapeInputSelected +XRequest.SHAPE.8: X_ShapeGetRectangles +! Input extension, an X Consortium standard +XRequest.XInputExtension.1:X_GetExtensionVersion +XRequest.XInputExtension.2:X_ListInputDevices +XRequest.XInputExtension.3:X_OpenDevice +XRequest.XInputExtension.4:X_CloseDevice +XRequest.XInputExtension.5:X_SetDeviceMode +XRequest.XInputExtension.6:X_SelectExtensionEvent +XRequest.XInputExtension.7:X_GetSelectedExtensionEvents +XRequest.XInputExtension.8:X_ChangeDeviceDontPropagateList +XRequest.XInputExtension.9:X_GetDeviceDontPropagateList +XRequest.XInputExtension.10:X_GetDeviceMotionEvents +XRequest.XInputExtension.11:X_ChangeKeyboardDevice +XRequest.XInputExtension.12:X_ChangePointerDevice +XRequest.XInputExtension.13:X_GrabDevice +XRequest.XInputExtension.14:X_UngrabDevice +XRequest.XInputExtension.15:X_GrabDeviceKey +XRequest.XInputExtension.16:X_UngrabDeviceKey +XRequest.XInputExtension.17:X_GrabDeviceButton +XRequest.XInputExtension.18:X_UngrabDeviceButton +XRequest.XInputExtension.19:X_AllowDeviceEvents +XRequest.XInputExtension.20:X_GetDeviceFocus +XRequest.XInputExtension.21:X_SetDeviceFocus +XRequest.XInputExtension.22:X_GetFeedbackControl +XRequest.XInputExtension.23:X_ChangeFeedbackControl +XRequest.XInputExtension.24:X_GetDeviceKeyMapping +XRequest.XInputExtension.25:X_ChangeDeviceKeyMapping +XRequest.XInputExtension.26:X_GetDeviceModifierMapping +XRequest.XInputExtension.27:X_SetDeviceModifierMapping +XRequest.XInputExtension.28:X_GetDeviceButtonMapping +XRequest.XInputExtension.29:X_SetDeviceButtonMapping +XRequest.XInputExtension.30:X_QueryDeviceState +XRequest.XInputExtension.31:X_SendExtensionEvent +XRequest.XInputExtension.32:X_DeviceBell +XRequest.XInputExtension.33:X_SetDeviceValuators +XRequest.XInputExtension.34:X_GetDeviceControl +XRequest.XInputExtension.35:X_ChangeDeviceControl +! MIT-SHM extension, experimental, not an X Consortium standard +XRequest.MIT-SHM.0: X_ShmQueryVersion +XRequest.MIT-SHM.1: X_ShmAttach +XRequest.MIT-SHM.2: X_ShmDetach +XRequest.MIT-SHM.3: X_ShmPutImage +XRequest.MIT-SHM.4: X_ShmGetImage +XRequest.MIT-SHM.5: X_ShmCreatePixmap +XProtoError.MIT-SHM.0: BadShmSeg (invalid shared segment parameter) +XlibMessage.MIT-SHM.0: Segment id in failed request: 0x%lx +! MIT-SUNDRY-NONSTANDARD extension, definitely not an X Consortium standard +XRequest.MIT-SUNDRY-NONSTANDARD.0: X_MITSetBugMode +XRequest.MIT-SUNDRY-NONSTANDARD.1: X_MITGetBugMode +! X3D-PEX extension +XRequest.X3D-PEX.1: PEX_GetExtensionInfo +XRequest.X3D-PEX.2: PEX_GetEnumeratedTypeInfo +XRequest.X3D-PEX.3: PEX_GetImpDepConstants +XRequest.X3D-PEX.4: PEX_CreateLookupTable +XRequest.X3D-PEX.5: PEX_CopyLookupTable +XRequest.X3D-PEX.6: PEX_FreeLookupTable +XRequest.X3D-PEX.7: PEX_GetTableInfo +XRequest.X3D-PEX.8: PEX_GetPredefinedEntries +XRequest.X3D-PEX.9: PEX_GetDefinedIndices +XRequest.X3D-PEX.10: PEX_GetTableEntry +XRequest.X3D-PEX.11: PEX_GetTableEntries +XRequest.X3D-PEX.12: PEX_SetTableEntries +XRequest.X3D-PEX.13: PEX_DeleteTableEntries +XRequest.X3D-PEX.14: PEX_CreatePipelineContext +XRequest.X3D-PEX.15: PEX_CopyPipelineContext +XRequest.X3D-PEX.16: PEX_FreePipelineContext +XRequest.X3D-PEX.17: PEX_GetPipelineContext +XRequest.X3D-PEX.18: PEX_ChangePipelineContext +XRequest.X3D-PEX.19: PEX_CreateRenderer +XRequest.X3D-PEX.20: PEX_FreeRenderer +XRequest.X3D-PEX.21: PEX_ChangeRenderer +XRequest.X3D-PEX.22: PEX_GetRendererAttributes +XRequest.X3D-PEX.23: PEX_GetRendererDynamics +XRequest.X3D-PEX.24: PEX_BeginRendering +XRequest.X3D-PEX.25: PEX_EndRendering +XRequest.X3D-PEX.26: PEX_BeginStructure +XRequest.X3D-PEX.27: PEX_EndStructure +XRequest.X3D-PEX.28: PEX_RenderOutputCommands +XRequest.X3D-PEX.29: PEX_RenderNetwork +XRequest.X3D-PEX.30: PEX_CreateStructure +XRequest.X3D-PEX.31: PEX_CopyStructure +XRequest.X3D-PEX.32: PEX_DestroyStructures +XRequest.X3D-PEX.33: PEX_GetStructureInfo +XRequest.X3D-PEX.34: PEX_GetElementInfo +XRequest.X3D-PEX.35: PEX_GetStructuresInNetwork +XRequest.X3D-PEX.36: PEX_GetAncestors +XRequest.X3D-PEX.37: PEX_GetDescendants +XRequest.X3D-PEX.38: PEX_FetchElements +XRequest.X3D-PEX.39: PEX_SetEditingMode +XRequest.X3D-PEX.40: PEX_SetElementPointer +XRequest.X3D-PEX.41: PEX_SetElementPointerAtLabel +XRequest.X3D-PEX.42: PEX_ElementSearch +XRequest.X3D-PEX.43: PEX_StoreElements +XRequest.X3D-PEX.44: PEX_DeleteElements +XRequest.X3D-PEX.45: PEX_DeleteElementsToLabel +XRequest.X3D-PEX.46: PEX_DeleteBetweenLabels +XRequest.X3D-PEX.47: PEX_CopyElements +XRequest.X3D-PEX.48: PEX_ChangeStructureRefs +XRequest.X3D-PEX.49: PEX_CreateNameSet +XRequest.X3D-PEX.50: PEX_CopyNameSet +XRequest.X3D-PEX.51: PEX_FreeNameSet +XRequest.X3D-PEX.52: PEX_GetNameSet +XRequest.X3D-PEX.53: PEX_ChangeNameSet +XRequest.X3D-PEX.54: PEX_CreateSearchContext +XRequest.X3D-PEX.55: PEX_CopySearchContext +XRequest.X3D-PEX.56: PEX_FreeSearchContext +XRequest.X3D-PEX.57: PEX_GetSearchContext +XRequest.X3D-PEX.58: PEX_ChangeSearchContext +XRequest.X3D-PEX.59: PEX_SearchNetwork +XRequest.X3D-PEX.60: PEX_CreatePhigsWks +XRequest.X3D-PEX.61: PEX_FreePhigsWks +XRequest.X3D-PEX.62: PEX_GetWksInfo +XRequest.X3D-PEX.63: PEX_GetDynamics +XRequest.X3D-PEX.64: PEX_GetViewRep +XRequest.X3D-PEX.65: PEX_RedrawAllStructures +XRequest.X3D-PEX.66: PEX_UpdateWorkstation +XRequest.X3D-PEX.67: PEX_RedrawClipRegion +XRequest.X3D-PEX.68: PEX_ExecuteDeferredActions +XRequest.X3D-PEX.69: PEX_SetViewPriority +XRequest.X3D-PEX.70: PEX_SetDisplayUpdateMode +XRequest.X3D-PEX.71: PEX_MapDCtoWC +XRequest.X3D-PEX.72: PEX_MapWCtoDC +XRequest.X3D-PEX.73: PEX_SetViewRep +XRequest.X3D-PEX.74: PEX_SetWksWindow +XRequest.X3D-PEX.75: PEX_SetWksViewport +XRequest.X3D-PEX.76: PEX_SetHlhsrMode +XRequest.X3D-PEX.77: PEX_SetWksBufferMode +XRequest.X3D-PEX.78: PEX_PostStructure +XRequest.X3D-PEX.79: PEX_UnpostStructure +XRequest.X3D-PEX.80: PEX_UnpostAllStructures +XRequest.X3D-PEX.81: PEX_GetWksPostings +XRequest.X3D-PEX.82: PEX_GetPickDevice +XRequest.X3D-PEX.83: PEX_ChangePickDevice +XRequest.X3D-PEX.84: PEX_CreatePickMeasure +XRequest.X3D-PEX.85: PEX_FreePickMeasure +XRequest.X3D-PEX.86: PEX_GetPickMeasure +XRequest.X3D-PEX.87: PEX_UpdatePickMeasure +XRequest.X3D-PEX.88: PEX_OpenFont +XRequest.X3D-PEX.89: PEX_CloseFont +XRequest.X3D-PEX.90: PEX_QueryFont +XRequest.X3D-PEX.91: PEX_ListFonts +XRequest.X3D-PEX.92: PEX_ListFontsWithInfo +XRequest.X3D-PEX.93: PEX_QueryTextExtents +XRequest.X3D-PEX.94: PEX_MatchRenderingTargets +XRequest.X3D-PEX.95: PEX_Escape +XRequest.X3D-PEX.96: PEX_EscapeWithReply +XRequest.X3D-PEX.97: PEX_RenderElements +XRequest.X3D-PEX.98: PEX_AccumulateState +XRequest.X3D-PEX.99: PEX_BeginPickOne +XRequest.X3D-PEX.100: PEX_EndPickOne +XRequest.X3D-PEX.101: PEX_PickOne +XRequest.X3D-PEX.102: PEX_BeginPickAll +XRequest.X3D-PEX.103: PEX_EndPickAll +XRequest.X3D-PEX.104: PEX_PickAll +XProtoError.X3D-PEX.0: PEXColorTypeError +XlibMessage.X3D-PEX.0: Color type in failed request: 0x%lx +XProtoError.X3D-PEX.1: PEXRendererStateError +XlibMessage.X3D-PEX.1: Renderer id in failed request: 0x%lx +XProtoError.X3D-PEX.2: PEXFloatingPointFormatError +XlibMessage.X3D-PEX.2: Format in failed request: 0x%lx +XProtoError.X3D-PEX.3: PEXLabelError +XlibMessage.X3D-PEX.3: Label in failed request: 0x%lx +XProtoError.X3D-PEX.4: PEXLookupTableError +XlibMessage.X3D-PEX.4: Table id in failed request: 0x%lx +XProtoError.X3D-PEX.5: PEXNameSetError +XlibMessage.X3D-PEX.5: Nameset in failed request: 0x%lx +XProtoError.X3D-PEX.6: PEXPathError +XlibMessage.X3D-PEX.6: Path id in failed request: 0x%lx +XProtoError.X3D-PEX.7: PEXFontError +XlibMessage.X3D-PEX.7: Font id in failed request: 0x%lx +XProtoError.X3D-PEX.8: PEXPhigsWksError +XlibMessage.X3D-PEX.8: Workstation id in failed request: 0x%lx +XProtoError.X3D-PEX.9: PEXPickMeasureError +XlibMessage.X3D-PEX.9: Device id in failed request: 0x%lx +XProtoError.X3D-PEX.10: PEXPipelineContextError +XlibMessage.X3D-PEX.10: Context id in failed request: 0x%lx +XProtoError.X3D-PEX.11: PEXRendererError +XlibMessage.X3D-PEX.11: Renderer id in failed request: 0x%lx +XProtoError.X3D-PEX.12: PEXSearchContextError +XlibMessage.X3D-PEX.12: Context id in failed request: 0x%lx +XProtoError.X3D-PEX.13: PEXStructureError +XlibMessage.X3D-PEX.13: Structure id in failed request: 0x%lx +XProtoError.X3D-PEX.14: PEXOutputCommandError +XlibMessage.X3D-PEX.14: Resource id in failed request: 0x%lx +! XTEST extension, an X Consortium standard +XRequest.XTEST.0: X_XTestGetVersion +XRequest.XTEST.1: X_XTestCompareCursor +XRequest.XTEST.2: X_XTestFakeInput +! BIG-REQUESTS extension, an X Consortium standard +XRequest.BIG-REQUESTS.0: X_BigReqEnable +! XIE extension, an X Consortium standard +XRequest.XIE.1: XIE_QueryImageExtension +XRequest.XIE.2: XIE_QueryTechniques +XRequest.XIE.3: XIE_CreateColorList +XRequest.XIE.4: XIE_DestroyColorList +XRequest.XIE.5: XIE_PurgeColorList +XRequest.XIE.6: XIE_QueryColorList +XRequest.XIE.7: XIE_CreateLUT +XRequest.XIE.8: XIE_DestroyLUT +XRequest.XIE.9: XIE_CreatePhotomap +XRequest.XIE.10: XIE_DestroyPhotomap +XRequest.XIE.11: XIE_QueryPhotomap +XRequest.XIE.12: XIE_CreateROI +XRequest.XIE.13: XIE_DestroyROI +XRequest.XIE.14: XIE_CreatePhotospace +XRequest.XIE.15: XIE_DestroyPhotospace +XRequest.XIE.16: XIE_ExecuteImmediate +XRequest.XIE.17: XIE_CreatePhotoflo +XRequest.XIE.18: XIE_DestroyPhotoflo +XRequest.XIE.19: XIE_ExecutePhotoflo +XRequest.XIE.20: XIE_ModifyPhotoflo +XRequest.XIE.21: XIE_RedefinePhotoflo +XRequest.XIE.22: XIE_PutClientData +XRequest.XIE.23: XIE_GetClientData +XRequest.XIE.24: XIE_QueryPhotoflo +XRequest.XIE.25: XIE_Await +XRequest.XIE.26: XIE_Abort +XProtoError.XIE.0: XIE_ColorListError +XlibMessage.XIE.0: ColorList in failed request: 0x%lx +XProtoError.XIE.1: XIE_LUTError +XlibMessage.XIE.1: LUT in failed request: 0x%lx +XProtoError.XIE.2: XIE_PhotofloError +XlibMessage.XIE.2: Photoflo in failed request: 0x%lx +XProtoError.XIE.3: XIE_PhotomapError +XlibMessage.XIE.3: Photomap in failed request: 0x%lx +XProtoError.XIE.4: XIE_PhotospaceError +XlibMessage.XIE.4: Photospace in failed request: 0x%lx +XProtoError.XIE.5: XIE_ROIError +XlibMessage.XIE.5: ROI in failed request: 0x%lx +XProtoError.XIE.6: XIE_FloError +XlibMessage.XIE.6: Photoflo in failed request: 0x%lx +! SYNC extension, an X Consortium standard +XRequest.SYNC.0: X_SyncInitialize +XRequest.SYNC.1: X_SyncListSystemCounters +XRequest.SYNC.2: X_SyncCreateCounter +XRequest.SYNC.3: X_SyncSetCounter +XRequest.SYNC.4: X_SyncChangeCounter +XRequest.SYNC.5: X_SyncQueryCounter +XRequest.SYNC.6: X_SyncDestroyCounter +XRequest.SYNC.7: X_SyncAwait +XRequest.SYNC.8: X_SyncCreateAlarm +XRequest.SYNC.9: X_SyncChangeAlarm +XRequest.SYNC.10: X_SyncQueryAlarm +XRequest.SYNC.11: X_SyncDestroyAlarm +XRequest.SYNC.12: X_SyncSetPriority +XRequest.SYNC.13: X_SyncGetPriority +XProtoError.SYNC.0: XSyncBadCounter +XlibMessage.SYNC.0: Counter in failed request: 0x%lx +XProtoError.SYNC.1: XSyncBadAlarm +XlibMessage.SYNC.1: Alarm in failed request: 0x%lx +! XKB extension +XRequest.XKEYBOARD.0: XkbUseExtension +XRequest.XKEYBOARD.1: XkbSelectEvents +XRequest.XKEYBOARD.2: OBSOLETE +XRequest.XKEYBOARD.3: XkbBell +XRequest.XKEYBOARD.4: XkbGetState +XRequest.XKEYBOARD.5: XkbLatchLockState +XRequest.XKEYBOARD.6: XkbGetControls +XRequest.XKEYBOARD.7: XkbSetControls +XRequest.XKEYBOARD.8: XkbGetMap +XRequest.XKEYBOARD.9: XkbSetMap +XRequest.XKEYBOARD.10: XkbGetCompatMap +XRequest.XKEYBOARD.11: XkbSetCompatMap +XRequest.XKEYBOARD.12: XkbGetIndicatorState +XRequest.XKEYBOARD.13: XkbGetIndicatorMap +XRequest.XKEYBOARD.14: XkbSetIndicatorMap +XRequest.XKEYBOARD.15: XkbGetNamedIndicator +XRequest.XKEYBOARD.16: XkbSetNamedIndicator +XRequest.XKEYBOARD.17: XkbGetNames +XRequest.XKEYBOARD.18: XkbSetNames +XRequest.XKEYBOARD.19: XkbGetGeometry +XRequest.XKEYBOARD.20: XkbSetGeometry +XRequest.XKEYBOARD.21: XkbPerClientFlags +XRequest.XKEYBOARD.22: XkbListComponents +XRequest.XKEYBOARD.23: XkbGetKbdByName +XRequest.XKEYBOARD.24: XkbGetDeviceInfo +XRequest.XKEYBOARD.25: XkbSetDeviceInfo +XRequest.XKEYBOARD.101: XkbSetDebuggingFlags +XProtoError.XKEYBOARD.0: XkbBadKeyboard +XlibMessage.XKEYBOARD.0: Device id in failed request: 0x%lx +! GLX extension for OpenGL, an OpenGL Architectural Review Board standard +! GLX Commands +XRequest.GLX.7: X_GLXQueryVersion +XRequest.GLX.3: X_GLXCreateContext +XRequest.GLX.4: X_GLXDestroyContext +XRequest.GLX.5: X_GLXMakeCurrent +XRequest.GLX.6: X_GLXIsDirect +XRequest.GLX.10: X_GLXCopyContext +XRequest.GLX.8: X_GLXWaitGL +XRequest.GLX.9: X_GLXWaitX +XRequest.GLX.11: X_GLXSwapBuffers +XRequest.GLX.12: X_GLXUseXFont +XRequest.GLX.13: X_GLXCreateGLXPixmap +XRequest.GLX.15: X_GLXDestroyGLXPixmap +XRequest.GLX.14: X_GLXGetVisualConfigs +XRequest.GLX.16: X_GLXVendorPrivate +XRequest.GLX.17: X_GLXVendorPrivateWithReply +XRequest.GLX.18: X_GLXQueryExtensionsString +XRequest.GLX.19: X_GLXQueryServerString +XRequest.GLX.20: X_GLXClientInfo +! GL Non-rendering Commands +XRequest.GLX.103: X_GLXDeleteLists +XRequest.GLX.102: X_GLXEndList +XRequest.GLX.105: X_GLXFeedbackBuffer +XRequest.GLX.108: X_GLXFinish +XRequest.GLX.142: X_GLXFlush +XRequest.GLX.104: X_GLXGenLists +XRequest.GLX.112: X_GLXGetBooleanv +XRequest.GLX.113: X_GLXGetClipPlane +XRequest.GLX.114: X_GLXGetDoublev +XRequest.GLX.115: X_GLXGetError +XRequest.GLX.116: X_GLXGetFloatv +XRequest.GLX.117: X_GLXGetIntegerv +XRequest.GLX.118: X_GLXGetLightfv +XRequest.GLX.119: X_GLXGetLightiv +XRequest.GLX.120: X_GLXGetMapdv +XRequest.GLX.121: X_GLXGetMapfv +XRequest.GLX.122: X_GLXGetMapiv +XRequest.GLX.123: X_GLXGetMaterialfv +XRequest.GLX.124: X_GLXGetMaterialiv +XRequest.GLX.125: X_GLXGetPixelfv +XRequest.GLX.126: X_GLXGetPixelMapuiv +XRequest.GLX.127: X_GLXGetPixelMapusv +XRequest.GLX.129: X_GLXGetString +XRequest.GLX.130: X_GLXGetTexEnvfv +XRequest.GLX.131: X_GLXGetTexEnviv +XRequest.GLX.132: X_GLXGetTexGendv +XRequest.GLX.133: X_GLXGetTexGenfv +XRequest.GLX.134: X_GLXGetTexGeniv +XRequest.GLX.138: X_GLXGetTexLevelParameterfv +XRequest.GLX.139: X_GLXGetTexLevelParameteriv +XRequest.GLX.136: X_GLXGetTexParameterfv +XRequest.GLX.137: X_GLXGetTexParameteriv +XRequest.GLX.140: X_GLXIsEnabled +XRequest.GLX.141: X_GLXIsList +XRequest.GLX.101: X_GLXNewList +XRequest.GLX.109: X_GLXPixelStoref +XRequest.GLX.110: X_GLXPixelStorei +XRequest.GLX.107: X_GLXRenderMode +XRequest.GLX.106: X_GLXSelectBuffer +! GL Non-rendering Commands That Return Pixel Data +XRequest.GLX.128: X_GLXGetPolygonStipple +XRequest.GLX.135: X_GLXGetTexImage +XRequest.GLX.111: X_GLXReadPixels +! GL Rendering Commands +XRequest.GLX.1: X_GLXRender +XRequest.GLX.2: X_GLXRenderLarge +! GLX Errors +XProtoError.GLX.0: GLXBadContext +XProtoError.GLX.1: GLXBadContextState +XProtoError.GLX.2: GLXBadDrawable +XProtoError.GLX.3: GLXBadPixmap +XProtoError.GLX.4: GLXBadContextTag +XProtoError.GLX.5: GLXBadCurrentWindow +XProtoError.GLX.6: GLXBadRenderRequest +XProtoError.GLX.7: GLXBadLargeRequest +XProtoError.GLX.8: GLXUnsupportedPrivateRequest +! XC-MISC extension, an X Consortium standard +XRequest.XC-MISC.0: XCMiscGetVersion +XRequest.XC-MISC.1: XCMiscGetXIDRange +! RECORD extension +XRequest.RECORD.0: XRecordQueryVersion +XRequest.RECORD.1: XRecordCreateContext +XRequest.RECORD.2: XRecordRegisterClients +XRequest.RECORD.3: XRecordUnregisterClients +XRequest.RECORD.4: XRecordGetContext +XRequest.RECORD.5: XRecordEnableContext +XRequest.RECORD.6: XRecordDisableContext +XRequest.RECORD.7: XRecordFreeContext +XProtoError.RECORD.0: XRecordBadContext +XlibMessage.RECORD.0: Context in failed request: 0x%lx +! XFree86-VidModeExtension -- not an X Consortium standard +XRequest.XFree86-VidModeExtension.0: XF86VidModeQueryVersion +XRequest.XFree86-VidModeExtension.1: XF86VidModeGetModeLine +XRequest.XFree86-VidModeExtension.2: XF86VidModeModModeLine +XRequest.XFree86-VidModeExtension.3: XF86VidModeSwitchMode +XRequest.XFree86-VidModeExtension.4: XF86VidModeGetMonitor +XRequest.XFree86-VidModeExtension.5: XF86VidModeLockModeSwitch +XRequest.XFree86-VidModeExtension.6: XF86VidModeGetAllModeLines +XRequest.XFree86-VidModeExtension.7: XF86VidModeAddModeLine +XRequest.XFree86-VidModeExtension.8: XF86VidModeDeleteModeLine +XRequest.XFree86-VidModeExtension.9: XF86VidModeValidateModeLine +XRequest.XFree86-VidModeExtension.10: XF86VidModeSwitchToMode +XRequest.XFree86-VidModeExtension.11: XF86VidModeGetViewPort +XRequest.XFree86-VidModeExtension.12: XF86VidModeSetViewPort +XProtoError.XFree86-VidModeExtension.0: XF86VidModeBadClock +XProtoError.XFree86-VidModeExtension.1: XF86VidModeBadHTimings +XProtoError.XFree86-VidModeExtension.2: XF86VidModeBadVTimings +XProtoError.XFree86-VidModeExtension.3: XF86VidModeModeUnsuitable +XProtoError.XFree86-VidModeExtension.4: XF86VidModeClientNotLocal +XProtoError.XFree86-VidModeExtension.5: XF86VidModeExtensionDisabled +XProtoError.XFree86-VidModeExtension.6: XF86VidModeZoomLocked +! XFree86-Misc -- not an X Consortium standard +XRequest.XFree86-Misc.0: XF86MiscQueryVersion +XRequest.XFree86-Misc.1: XF86MiscGetSaver +XRequest.XFree86-Misc.2: XF86MiscSetSaver +XRequest.XFree86-Misc.3: XF86MiscGetMouseSettings +XRequest.XFree86-Misc.4: XF86MiscGetKbdSettings +XRequest.XFree86-Misc.5: XF86MiscSetMouseSettings +XRequest.XFree86-Misc.6: XF86MiscSetKbdSettings +XProtoError.XFree86-Misc.0: XF86MiscBadMouseProtocol +XProtoError.XFree86-Misc.1: XF86MiscBadMouseBaudRate +XProtoError.XFree86-Misc.2: XF86MiscBadMouseFlags +XProtoError.XFree86-Misc.3: XF86MiscBadMouseCombo +XProtoError.XFree86-Misc.4: XF86MiscBadKbdType +XProtoError.XFree86-Misc.5: XF86MiscModInDevDisabled +XProtoError.XFree86-Misc.6: XF86MiscModInDevClientNotLocal +! XFree86-DGA -- not an X Consortium standard +XRequest.XFree86-DGA.0: XF86DGAQueryVersion +XRequest.XFree86-DGA.1: XF86DGAGetVideoLL +XRequest.XFree86-DGA.2: XF86DGADirectVideo +XRequest.XFree86-DGA.3: XF86DGAGetViewPortSize +XRequest.XFree86-DGA.4: XF86DGASetViewPort +XRequest.XFree86-DGA.5: XF86DGAGetVidPage +XRequest.XFree86-DGA.6: XF86DGASetVidPage +XRequest.XFree86-DGA.7: XF86DGAInstallColormap +XRequest.XFree86-DGA.8: XF86DGAQueryDirectVideo +XRequest.XFree86-DGA.9: XF86DGAViewPortChanged +XProtoError.XFree86-DGA.0: XF86DGAClientNotLocal +XProtoError.XFree86-DGA.1: XF86DGANoDirectVideoMode +XProtoError.XFree86-DGA.2: XF86DGAScreenNotActive +XProtoError.XFree86-DGA.3: XF86DGADirectNotActivated +! DOUBLE-BUFFER (DBE), an X Consortium standard +XRequest.DOUBLE-BUFFER.0: DBEGetVersion +XRequest.DOUBLE-BUFFER.1: DBEAllocateBackBufferName +XRequest.DOUBLE-BUFFER.2: DBEDeallocateBackBufferName +XRequest.DOUBLE-BUFFER.3: DBESwapBuffers +XRequest.DOUBLE-BUFFER.4: DBEBeginIdiom +XRequest.DOUBLE-BUFFER.5: DBEEndIdiom +XRequest.DOUBLE-BUFFER.6: DBEGetVisualInfo +XRequest.DOUBLE-BUFFER.7: DBEGetBackBufferAttributes +XProtoError.DOUBLE-BUFFER.0: DBEBadBuffer (invalid BackBuffer parameter) +XlibMessage.DOUBLE-BUFFER.0: BackBuffer in failed request: 0x%lx +! SECURITY +XRequest.SECURITY.0: SecurityQueryVersion +XRequest.SECURITY.1: SecurityGenerateAuthorization +XProtoError.SECURITY.0: SecurityBadAuthorization (invalid authorization id) +XProtoError.SECURITY.1: SecurityBadAuthorizationProtocol (invalid authorization name or data) +XlibMessage.SECURITY.1: authorization id in failed request: 0x%lx +! AppGroup +XRequest.APPGROUP.0: XagQueryVersion +XRequest.APPGROUP.1: XagCreate +XRequest.APPGROUP.2: XagDestroy +XRequest.APPGROUP.3: XagGetAttr +XRequest.APPGROUP.4: XagQuery +XRequest.APPGROUP.5: XagCreateAssoc +XRequest.APPGROUP.6: XagDestroyAssoc +XProtoError.APPGROUP.0: XagBadAppGroup (invalid AppGroup parameter) +! LBX +XRequest.LBX.0: LbxQueryVersion +XRequest.LBX.1: LbxStartProxy +XRequest.LBX.2: LbxStopProxy +XRequest.LBX.3: LbxSwitch +XRequest.LBX.4: LbxNewClient +XRequest.LBX.5: LbxCloseClient +XRequest.LBX.6: LbxModifySequence +XRequest.LBX.7: LbxAllowMotion +XRequest.LBX.8: LbxIncrementPixel +XRequest.LBX.9: LbxDelta +XRequest.LBX.10: LbxGetModifierMapping +XRequest.LBX.11: LbxQueryTag +XRequest.LBX.12: LbxInvalidateTag +XRequest.LBX.13: LbxPolyPoint +XRequest.LBX.14: LbxPolyLine +XRequest.LBX.15: LbxPolySegment +XRequest.LBX.16: LbxPolyRectangle +XRequest.LBX.17: LbxPolyArc +XRequest.LBX.18: LbxFillPoly +XRequest.LBX.19: LbxPolyFillRectangle +XRequest.LBX.20: LbxPolyFillArc +XRequest.LBX.21: LbxGetKeyboardMapping +XRequest.LBX.22: LbxQueryFont +XRequest.LBX.23: LbxChangeProperty +XRequest.LBX.24: LbxGetProperty +XRequest.LBX.25: LbxTagData +XRequest.LBX.26: LbxCopyArea +XRequest.LBX.27: LbxCopyPlane +XRequest.LBX.28: LbxPolyText8 +XRequest.LBX.29: LbxPolyText16 +XRequest.LBX.30: LbxImageText8 +XRequest.LBX.31: LbxImageText16 +XRequest.LBX.32: LbxQueryExtension +XRequest.LBX.33: LbxPutImage +XRequest.LBX.34: LbxGetImage +XRequest.LBX.35: LbxBeginLargeRequest +XRequest.LBX.36: LbxLargeRequestData +XRequest.LBX.37: LbxEndLargeRequest +XRequest.LBX.38: LbxInternAtoms +XRequest.LBX.39: LbxGetWinAttrAndGeom +XRequest.LBX.40: LbxGrabCmap +XRequest.LBX.41: LbxReleaseCmap +XRequest.LBX.42: LbxAllocColor +XRequest.LBX.43: LbxSync +XProtoError.LBX.0: BadLbxClient +! XpExtension +XRequest.XpExtension.0: PrintQueryVersion +XRequest.XpExtension.1: PrintGetPrinterList +XRequest.XpExtension.2: PrintCreateContext +XRequest.XpExtension.3: PrintSetContext +XRequest.XpExtension.4: PrintGetContext +XRequest.XpExtension.5: PrintDestroyContext +XRequest.XpExtension.6: PrintGetContextScreen +XRequest.XpExtension.7: PrintStartJob +XRequest.XpExtension.8: PrintEndJob +XRequest.XpExtension.9: PrintStartDoc +XRequest.XpExtension.10: PrintEndDoc +XRequest.XpExtension.11: PrintPutDocumentData +XRequest.XpExtension.12: PrintGetDocumentData +XRequest.XpExtension.13: PrintStartPage +XRequest.XpExtension.14: PrintEndPage +XRequest.XpExtension.15: PrintSelectInput +XRequest.XpExtension.16: PrintInputSelected +XRequest.XpExtension.17: PrintGetAttributes +XRequest.XpExtension.18: PrintSetAttributes +XRequest.XpExtension.19: PrintGetOneAttribute +XRequest.XpExtension.20: PrintRehashPrinterList +XRequest.XpExtension.21: PrintGetPageDimensions +XRequest.XpExtension.22: PrintQueryScreens +XRequest.XpExtension.23: PrintSetImageResolution +XRequest.XpExtension.24: PrintGetImageResolution +XProtoError.XpExtension.0: XPBadContext (Print Context invalid or missing) +XlibMessage.XpExtension.0: Context in failed request: 0x%lx +XProtoError.XpExtension.1: XPBadSequence (Illegal sequence of XP operations) +XProtoError.XpExtension.2: XPBadResourceID (X resource not valid) +! TOG-CUP, an X Project Team specification +XRequest.TOG-CUP.0: CUPQueryVersion +XRequest.TOG-CUP.1: CUPGetReservedColormapEntries +XRequest.TOG-CUP.2: CUPStoreColors +! Extended-Visual-Information, an X Project Team specification +XRequest.Extended-Visual-Information.0: EVIQueryVersion +XRequest.Extended-Visual-Information.1: EVIGetVisualInfo +! DPMS (Display Power Management Signaling), an X Project Team specification +XRequest.DPMS.0: DPMSGetVersion +XRequest.DPMS.1: DPMSCapable +XRequest.DPMS.2: DPMSGetTimeouts +XRequest.DPMS.3: DPMSSetTimeouts +XRequest.DPMS.4: DPMSEnable +XRequest.DPMS.5: DPMSDisable +XRequest.DPMS.6: DPMSForceLevel +XRequest.DPMS.7: DPMSInfo +! XINERAMA, not an X Project Team specification +XRequest.XINERAMA.0: XINERAMAQueryVersion +XRequest.XINERAMA.1: XINERAMAGetState +XRequest.XINERAMA.2: XINERAMAGetScreenCount +XRequest.XINERAMA.3: XINERAMAGetScreenSize diff --git a/src/XKeysymDB b/src/XKeysymDB new file mode 100644 index 00000000..70575cec --- /dev/null +++ b/src/XKeysymDB @@ -0,0 +1,206 @@ +! $Xorg: XKeysymDB,v 1.3 2000/08/17 19:45:04 cpqbld Exp $ +! Copyright 1993 Massachusetts Institute of Technology +! +! 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 M.I.T. not be used in advertising or +! publicity pertaining to distribution of the software without specific, +! written prior permission. M.I.T. makes no representations about the +! suitability of this software for any purpose. It is provided "as is" +! without express or implied warranty. + +hpmute_acute :100000A8 +hpmute_grave :100000A9 +hpmute_asciicircum :100000AA +hpmute_diaeresis :100000AB +hpmute_asciitilde :100000AC +hplira :100000AF +hpguilder :100000BE +hpYdiaeresis :100000EE +hpIO :100000EE +hplongminus :100000F6 +hpblock :100000FC +apLineDel :1000FF00 +apCharDel :1000FF01 +apCopy :1000FF02 +apCut :1000FF03 +apPaste :1000FF04 +apMove :1000FF05 +apGrow :1000FF06 +apCmd :1000FF07 +apShell :1000FF08 +apLeftBar :1000FF09 +apRightBar :1000FF0A +apLeftBox :1000FF0B +apRightBox :1000FF0C +apUpBox :1000FF0D +apDownBox :1000FF0E +apPop :1000FF0F +apRead :1000FF10 +apEdit :1000FF11 +apSave :1000FF12 +apExit :1000FF13 +apRepeat :1000FF14 +hpModelock1 :1000FF48 +hpModelock2 :1000FF49 +hpReset :1000FF6C +hpSystem :1000FF6D +hpUser :1000FF6E +hpClearLine :1000FF6F +hpInsertLine :1000FF70 +hpDeleteLine :1000FF71 +hpInsertChar :1000FF72 +hpDeleteChar :1000FF73 +hpBackTab :1000FF74 +hpKP_BackTab :1000FF75 +apKP_parenleft :1000FFA8 +apKP_parenright :1000FFA9 + +I2ND_FUNC_L :10004001 +I2ND_FUNC_R :10004002 +IREMOVE :10004003 +IREPEAT :10004004 +IA1 :10004101 +IA2 :10004102 +IA3 :10004103 +IA4 :10004104 +IA5 :10004105 +IA6 :10004106 +IA7 :10004107 +IA8 :10004108 +IA9 :10004109 +IA10 :1000410A +IA11 :1000410B +IA12 :1000410C +IA13 :1000410D +IA14 :1000410E +IA15 :1000410F +IB1 :10004201 +IB2 :10004202 +IB3 :10004203 +IB4 :10004204 +IB5 :10004205 +IB6 :10004206 +IB7 :10004207 +IB8 :10004208 +IB9 :10004209 +IB10 :1000420A +IB11 :1000420B +IB12 :1000420C +IB13 :1000420D +IB14 :1000420E +IB15 :1000420F +IB16 :10004210 + +DRemove :1000FF00 +Dring_accent :1000FEB0 +Dcircumflex_accent :1000FE5E +Dcedilla_accent :1000FE2C +Dacute_accent :1000FE27 +Dgrave_accent :1000FE60 +Dtilde :1000FE7E +Ddiaeresis :1000FE22 + +osfCopy :1004FF02 +osfCut :1004FF03 +osfPaste :1004FF04 +osfBackTab :1004FF07 +osfBackSpace :1004FF08 +osfClear :1004FF0B +osfEscape :1004FF1B +osfAddMode :1004FF31 +osfPrimaryPaste :1004FF32 +osfQuickPaste :1004FF33 +osfPageLeft :1004FF40 +osfPageUp :1004FF41 +osfPageDown :1004FF42 +osfPageRight :1004FF43 +osfActivate :1004FF44 +osfMenuBar :1004FF45 +osfLeft :1004FF51 +osfUp :1004FF52 +osfRight :1004FF53 +osfDown :1004FF54 +osfPrior :1004FF55 +osfNext :1004FF56 +osfEndLine :1004FF57 +osfBeginLine :1004FF58 +osfEndData :1004FF59 +osfBeginData :1004FF5A +osfPrevMenu :1004FF5B +osfNextMenu :1004FF5C +osfPrevField :1004FF5D +osfNextField :1004FF5E +osfSelect :1004FF60 +osfInsert :1004FF63 +osfUndo :1004FF65 +osfMenu :1004FF67 +osfCancel :1004FF69 +osfHelp :1004FF6A +osfSelectAll :1004FF71 +osfDeselectAll :1004FF72 +osfReselect :1004FF73 +osfExtend :1004FF74 +osfRestore :1004FF78 +osfSwitchDirection :1004FF7E +osfPriorMinor :1004FFF5 +osfNextMinor :1004FFF6 +osfRightLine :1004FFF7 +osfLeftLine :1004FFF8 +osfDelete :1004FFFF + +SunFA_Grave :1005FF00 +SunFA_Circum :1005FF01 +SunFA_Tilde :1005FF02 +SunFA_Acute :1005FF03 +SunFA_Diaeresis :1005FF04 +SunFA_Cedilla :1005FF05 +SunF36 :1005FF10 +SunF37 :1005FF11 +SunSys_Req :1005FF60 +SunProps :1005FF70 +SunFront :1005FF71 +SunCopy :1005FF72 +SunOpen :1005FF73 +SunPaste :1005FF74 +SunCut :1005FF75 +SunPowerSwitch :1005FF76 +SunAudioLowerVolume :1005FF77 +SunAudioMute :1005FF78 +SunAudioRaiseVolume :1005FF79 +SunVideoDegauss :1005FF7A +SunVideoLowerBrightness :1005FF7B +SunVideoRaiseBrightness :1005FF7C +SunPowerSwitchShift :1005FF7D + +SunCompose :FF20 +SunPageUp :FF55 +SunPageDown :FF56 +SunPrint_Screen :FF61 +SunUndo :FF65 +SunAgain :FF66 +SunFind :FF68 +SunStop :FF69 +SunAltGraph :FF7E + +WYSetup :1006FF00 + +ncdSetup :1006FF00 + +XeroxPointerButton1 :10070001 +XeroxPointerButton2 :10070002 +XeroxPointerButton3 :10070003 +XeroxPointerButton4 :10070004 +XeroxPointerButton5 :10070005 + +XF86ModeLock :1008FF01 + +usldead_acute :100000A8 +usldead_grave :100000A9 +usldead_diaeresis :100000AB +usldead_asciicircum :100000AA +usldead_asciitilde :100000AC +usldead_cedilla :1000FE2C +usldead_ring :1000FEB0 diff --git a/src/Xatomtype.h b/src/Xatomtype.h new file mode 100644 index 00000000..7ab7e5a0 --- /dev/null +++ b/src/Xatomtype.h @@ -0,0 +1,134 @@ +/* $Xorg: Xatomtype.h,v 1.4 2001/02/09 02:03:38 xorgcvs Exp $ */ + +/*********************************************************** + +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. + +******************************************************************/ + +#ifndef _XATOMTYPE_H_ +#define _XATOMTYPE_H_ + +/* + * This files defines crock C structures for calling XGetWindowProperty and + * XChangeProperty. All fields must be longs as the semantics of property + * routines will handle conversion to and from actual 32 bit objects. If your + * compiler doesn't treat &structoflongs the same as &arrayoflongs[0], you + * will have some work to do. + */ + +#define BOOL long +#define SIGNEDINT long +#define UNSIGNEDINT unsigned long +#define RESOURCEID unsigned long + + +/* this structure may be extended, but do not change the order */ +typedef struct { + UNSIGNEDINT flags; + SIGNEDINT x, y, width, height; /* need to cvt; only for pre-ICCCM */ + SIGNEDINT minWidth, minHeight; /* need to cvt */ + SIGNEDINT maxWidth, maxHeight; /* need to cvt */ + SIGNEDINT widthInc, heightInc; /* need to cvt */ + SIGNEDINT minAspectX, minAspectY; /* need to cvt */ + SIGNEDINT maxAspectX, maxAspectY; /* need to cvt */ + SIGNEDINT baseWidth,baseHeight; /* need to cvt; ICCCM version 1 */ + SIGNEDINT winGravity; /* need to cvt; ICCCM version 1 */ +} xPropSizeHints; +#define OldNumPropSizeElements 15 /* pre-ICCCM */ +#define NumPropSizeElements 18 /* ICCCM version 1 */ + +/* this structure may be extended, but do not change the order */ +/* RGB properties */ +typedef struct { + RESOURCEID colormap; + UNSIGNEDINT red_max; + UNSIGNEDINT red_mult; + UNSIGNEDINT green_max; + UNSIGNEDINT green_mult; + UNSIGNEDINT blue_max; + UNSIGNEDINT blue_mult; + UNSIGNEDINT base_pixel; + RESOURCEID visualid; /* ICCCM version 1 */ + RESOURCEID killid; /* ICCCM version 1 */ +} xPropStandardColormap; +#define OldNumPropStandardColormapElements 8 /* pre-ICCCM */ +#define NumPropStandardColormapElements 10 /* ICCCM version 1 */ + + +/* this structure may be extended, but do not change the order */ +typedef struct { + UNSIGNEDINT flags; + BOOL input; /* need to convert */ + SIGNEDINT initialState; /* need to cvt */ + RESOURCEID iconPixmap; + RESOURCEID iconWindow; + SIGNEDINT iconX; /* need to cvt */ + SIGNEDINT iconY; /* need to cvt */ + RESOURCEID iconMask; + UNSIGNEDINT windowGroup; + } xPropWMHints; +#define NumPropWMHintsElements 9 /* number of elements in this structure */ + +/* this structure defines the icon size hints information */ +typedef struct { + SIGNEDINT minWidth, minHeight; /* need to cvt */ + SIGNEDINT maxWidth, maxHeight; /* need to cvt */ + SIGNEDINT widthInc, heightInc; /* need to cvt */ + } xPropIconSize; +#define NumPropIconSizeElements 6 /* number of elements in this structure */ + +/* this structure defines the window manager state information */ +typedef struct { + SIGNEDINT state; /* need to cvt */ + RESOURCEID iconWindow; +} xPropWMState; +#define NumPropWMStateElements 2 /* number of elements in struct */ + +#undef BOOL +#undef SIGNEDINT +#undef UNSIGNEDINT +#undef RESOURCEID + +#endif /* _XATOMTYPE_H_ */ diff --git a/src/XlibAsync.c b/src/XlibAsync.c new file mode 100644 index 00000000..066e12e7 --- /dev/null +++ b/src/XlibAsync.c @@ -0,0 +1,153 @@ +/* $Xorg: XlibAsync.c,v 1.4 2001/02/09 02:03:38 xorgcvs Exp $ */ +/* + +Copyright 1992, 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. + +*/ + +#define NEED_REPLIES +#include <X11/Xlibint.h> +#include <X11/Xos.h> + +/*ARGSUSED*/ +Bool +_XAsyncErrorHandler(dpy, rep, buf, len, data) + register Display *dpy; + register xReply *rep; + char *buf; + int len; + XPointer data; +{ + register _XAsyncErrorState *state; + + state = (_XAsyncErrorState *)data; + if (rep->generic.type == X_Error && + (!state->error_code || + rep->error.errorCode == state->error_code) && + (!state->major_opcode || + rep->error.majorCode == state->major_opcode) && + (!state->minor_opcode || + rep->error.minorCode == state->minor_opcode) && + (!state->min_sequence_number || + (state->min_sequence_number <= dpy->last_request_read)) && + (!state->max_sequence_number || + (state->max_sequence_number >= dpy->last_request_read))) { + state->last_error_received = rep->error.errorCode; + state->error_count++; + return True; + } + return False; +} + +void _XDeqAsyncHandler(dpy, handler) + Display *dpy; + register _XAsyncHandler *handler; +{ + register _XAsyncHandler **prev; + register _XAsyncHandler *async; + + for (prev = &dpy->async_handlers; + (async = *prev) && (async != handler); + prev = &async->next) + ; + if (async) + *prev = async->next; +} + +char * +_XGetAsyncReply(dpy, replbuf, rep, buf, len, extra, discard) + register Display *dpy; + register char *replbuf; /* data is read into this buffer */ + register xReply *rep; /* value passed to calling handler */ + char *buf; /* value passed to calling handler */ + int len; /* value passed to calling handler */ + int extra; /* extra words to read, ala _XReply */ + Bool discard; /* discard after extra?, ala _XReply */ +{ + if (extra == 0) { + if (discard && (rep->generic.length << 2) > len) + _XEatData (dpy, (rep->generic.length << 2) - len); + return (char *)rep; + } + + if (extra <= rep->generic.length) { + int size = SIZEOF(xReply) + (extra << 2); + if (size > len) { + memcpy(replbuf, buf, len); + _XRead(dpy, replbuf + len, size - len); + buf = replbuf; + len = size; +#ifdef MUSTCOPY + } else { + memcpy(replbuf, buf, size); + buf = replbuf; +#endif + } + + if (discard && rep->generic.length > extra && + (rep->generic.length << 2) > len) + _XEatData (dpy, (rep->generic.length << 2) - len); + + return buf; + } + /* + *if we get here, then extra > rep->generic.length--meaning we + * read a reply that's shorter than we expected. This is an + * error, but we still need to figure out how to handle it... + */ + if ((rep->generic.length << 2) > len) + _XEatData (dpy, (rep->generic.length << 2) - len); + _XIOError (dpy); + return (char *)rep; +} + +void +_XGetAsyncData(dpy, data, buf, len, skip, datalen, discardtotal) + Display *dpy; + char *data; /* data is read into this buffer */ + char *buf; /* value passed to calling handler */ + int len; /* value passed to calling handler */ + int skip; /* number of bytes already read in previous + _XGetAsyncReply or _XGetAsyncData calls */ + int datalen; /* size of data buffer in bytes */ + int discardtotal; /* min. bytes to consume (after skip) */ +{ + buf += skip; + len -= skip; + if (!data) { + if (datalen > len) + _XEatData(dpy, datalen - len); + } else if (datalen <= len) { + memcpy(data, buf, datalen); + } else { + memcpy(data, buf, len); + _XRead(dpy, data + len, datalen - len); + } + if (discardtotal > len) { + if (datalen > len) + len = datalen; + _XEatData(dpy, discardtotal - len); + } +} diff --git a/src/XlibInt.c b/src/XlibInt.c new file mode 100644 index 00000000..a14cb333 --- /dev/null +++ b/src/XlibInt.c @@ -0,0 +1,3424 @@ +/* $Xorg: XlibInt.c,v 1.10 2001/02/20 02:13:26 coskrey Exp $ */ +/* + +Copyright 1985, 1986, 1987, 1998, 2001 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. + +*/ + +/* + * XlibInt.c - Internal support routines for the C subroutine + * interface library (Xlib) to the X Window System Protocol V11.0. + */ +#define NEED_EVENTS +#define NEED_REPLIES + +#define GENERIC_LENGTH_LIMIT (1 << 29) + +#include "Xlibint.h" +#include <X11/Xpoll.h> +#include <X11/Xtrans.h> +#include "xcmiscstr.h" +#include <stdio.h> + +#ifdef XTHREADS +#include "locking.h" + +/* these pointers get initialized by XInitThreads */ +LockInfoPtr _Xglobal_lock = NULL; +void (*_XCreateMutex_fn)() = NULL; +struct _XCVList *(*_XCreateCVL_fn)() = NULL; +void (*_XFreeMutex_fn)() = NULL; +void (*_XLockMutex_fn)() = NULL; +void (*_XUnlockMutex_fn)() = NULL; +xthread_t (*_Xthread_self_fn)() = NULL; + +#define XThread_Self() ((*_Xthread_self_fn)()) + +#define UnlockNextReplyReader(d) if ((d)->lock) \ + (*(d)->lock->pop_reader)((d),&(d)->lock->reply_awaiters,&(d)->lock->reply_awaiters_tail) + +#define QueueReplyReaderLock(d) ((d)->lock ? \ + (*(d)->lock->push_reader)(d,&(d)->lock->reply_awaiters_tail) : NULL) +#define QueueEventReaderLock(d) ((d)->lock ? \ + (*(d)->lock->push_reader)(d,&(d)->lock->event_awaiters_tail) : NULL) + +#if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE) +#define InternalLockDisplay(d,wskip) if ((d)->lock) \ + (*(d)->lock->internal_lock_display)(d,wskip,__FILE__,__LINE__) +#else +#define InternalLockDisplay(d,wskip) if ((d)->lock) \ + (*(d)->lock->internal_lock_display)(d,wskip) +#endif + +#else /* XTHREADS else */ + +#define UnlockNextReplyReader(d) +#define UnlockNextEventReader(d) +#define InternalLockDisplay(d,wskip) + +#endif /* XTHREADS else */ + +/* check for both EAGAIN and EWOULDBLOCK, because some supposedly POSIX + * systems are broken and return EWOULDBLOCK when they should return EAGAIN + */ +#ifdef WIN32 +#define ETEST() (WSAGetLastError() == WSAEWOULDBLOCK) +#else +#if defined(EAGAIN) && defined(EWOULDBLOCK) +#define ETEST() (errno == EAGAIN || errno == EWOULDBLOCK) +#else +#ifdef EAGAIN +#define ETEST() (errno == EAGAIN) +#else +#define ETEST() (errno == EWOULDBLOCK) +#endif +#endif +#endif +#ifdef WIN32 +#define ECHECK(err) (WSAGetLastError() == err) +#define ESET(val) WSASetLastError(val) +#else +#define ECHECK(err) (errno == err) +#define ESET(val) errno = val +#endif + +#if defined(LOCALCONN) || defined(LACHMAN) +#ifdef EMSGSIZE +#define ESZTEST() (ECHECK(EMSGSIZE) || ECHECK(ERANGE)) +#else +#define ESZTEST() ECHECK(ERANGE) +#endif +#else +#ifdef EMSGSIZE +#define ESZTEST() ECHECK(EMSGSIZE) +#endif +#endif + +#ifdef MUSTCOPY + +#define STARTITERATE(tpvar,type,start,endcond) \ + { register char *cpvar; \ + for (cpvar = (char *) (start); endcond; ) { \ + type dummy; memcpy ((char *) &dummy, cpvar, SIZEOF(type)); \ + tpvar = &dummy; +#define ITERPTR(tpvar) cpvar +#define RESETITERPTR(tpvar,type,start) cpvar = start +#define INCITERPTR(tpvar,type) cpvar += SIZEOF(type) +#define ENDITERATE }} + +#else + +#define STARTITERATE(tpvar,type,start,endcond) \ + for (tpvar = (type *) (start); endcond; ) +#define ITERPTR(tpvar) (char *)tpvar +#define RESETITERPTR(tpvar,type,start) tpvar = (type *) (start) +#define INCITERPTR(tpvar,type) tpvar++ +#define ENDITERATE + +#endif /* MUSTCOPY */ + +typedef union { + xReply rep; + char buf[BUFSIZE]; +} _XAlignedBuffer; + +static char *_XAsyncReply(); +static void _XProcessInternalConnection(); +#define SEQLIMIT (65535 - (BUFSIZE / SIZEOF(xReq)) - 10) + +/* + * The following routines are internal routines used by Xlib for protocol + * packet transmission and reception. + * + * _XIOError(Display *) will be called if any sort of system call error occurs. + * This is assumed to be a fatal condition, i.e., XIOError should not return. + * + * _XError(Display *, xError *) will be called whenever an X_Error event is + * received. This is not assumed to be a fatal condition, i.e., it is + * acceptable for this procedure to return. However, XError should NOT + * perform any operations (directly or indirectly) on the DISPLAY. + * + * Routines declared with a return type of 'Status' return 0 on failure, + * and non 0 on success. Routines with no declared return type don't + * return anything. Whenever possible routines that create objects return + * the object they have created. + */ + +static int padlength[4] = {0, 3, 2, 1}; + /* lookup table for adding padding bytes to data that is read from + or written to the X socket. */ + +static xReq _dummy_request = { + 0, 0, 0 +}; + +/* + * This is an OS dependent routine which: + * 1) returns as soon as the connection can be written on.... + * 2) if the connection can be read, must enqueue events and handle errors, + * until the connection is writable. + */ +static void +_XWaitForWritable(dpy +#ifdef XTHREADS + , cv +#endif + ) + Display *dpy; +#ifdef XTHREADS + xcondition_t cv; /* our reading condition variable */ +#endif +{ +#ifdef USE_POLL + struct pollfd filedes; +#else + fd_set r_mask; + fd_set w_mask; +#endif + int nfound; + +#ifdef USE_POLL + filedes.fd = dpy->fd; + filedes.events = 0; +#else + FD_ZERO(&r_mask); + FD_ZERO(&w_mask); +#endif + + for (;;) { +#ifdef XTHREADS + /* We allow only one thread at a time to read, to minimize + passing of read data between threads. + Now, who is it? If there is a non-NULL reply_awaiters and + we (i.e., our cv) are not at the head of it, then whoever + is at the head is the reader, and we don't read. + Otherwise there is no reply_awaiters or we are at the + head, having just appended ourselves. + In this case, if there is a event_awaiters, then whoever + is at the head of it got there before we did, and they are the + reader. + + Last cases: no event_awaiters and we are at the head of + reply_awaiters or reply_awaiters is NULL: we are the reader, + since there is obviously no one else involved. + + XXX - what if cv is NULL and someone else comes along after + us while we are waiting? + */ + + if (!dpy->lock || + (!dpy->lock->event_awaiters && + (!dpy->lock->reply_awaiters || + dpy->lock->reply_awaiters->cv == cv))) +#endif +#ifdef USE_POLL + filedes.events = POLLIN; + filedes.events |= POLLOUT; +#else + FD_SET(dpy->fd, &r_mask); + FD_SET(dpy->fd, &w_mask); +#endif + + do { + UnlockDisplay(dpy); +#ifdef USE_POLL + nfound = poll (&filedes, 1, -1); +#else + nfound = Select (dpy->fd + 1, &r_mask, &w_mask, NULL, NULL); +#endif + InternalLockDisplay(dpy, cv != NULL); + if (nfound < 0 && !ECHECK(EINTR)) + _XIOError(dpy); + } while (nfound <= 0); + + if ( +#ifdef USE_POLL + filedes.revents & POLLIN +#else + FD_ISSET(dpy->fd, &r_mask) +#endif + ) + { + _XAlignedBuffer buf; + BytesReadable_t pend; + register BytesReadable_t len; + register xReply *rep; + + /* find out how much data can be read */ + if (_X11TransBytesReadable(dpy->trans_conn, &pend) < 0) + _XIOError(dpy); + len = pend; + + /* must read at least one xEvent; if none is pending, then + we'll just block waiting for it */ + if (len < SIZEOF(xReply) +#ifdef XTHREADS + || dpy->async_handlers +#endif + ) + len = SIZEOF(xReply); + + /* but we won't read more than the max buffer size */ + if (len > BUFSIZE) len = BUFSIZE; + + /* round down to an integral number of XReps */ + len = (len / SIZEOF(xReply)) * SIZEOF(xReply); + + (void) _XRead (dpy, buf.buf, (long) len); + + STARTITERATE(rep,xReply,buf.buf,len > 0) { + if (rep->generic.type == X_Reply) { + pend = len; + RESETITERPTR(rep,xReply, + _XAsyncReply (dpy, rep, + ITERPTR(rep), &pend, True)); + len = pend; + } else { + if (rep->generic.type == X_Error) + _XError (dpy, (xError *)rep); + else /* must be an event packet */ + _XEnq (dpy, (xEvent *)rep); + INCITERPTR(rep,xReply); + len -= SIZEOF(xReply); + } + } ENDITERATE +#ifdef XTHREADS + if (dpy->lock && dpy->lock->event_awaiters) + ConditionSignal(dpy, dpy->lock->event_awaiters->cv); +#endif + } +#ifdef USE_POLL + if (filedes.revents & (POLLOUT|POLLHUP|POLLERR)) +#else + if (FD_ISSET(dpy->fd, &w_mask)) +#endif + { +#ifdef XTHREADS + if (dpy->lock) { + ConditionBroadcast(dpy, dpy->lock->writers); + } +#endif + return; + } + } +} + + +#define POLLFD_CACHE_SIZE 5 + +/* initialize the struct array passed to poll() below */ +Bool _XPollfdCacheInit(dpy) + Display *dpy; +{ +#ifdef USE_POLL + struct pollfd *pfp; + + pfp = (struct pollfd *)Xmalloc(POLLFD_CACHE_SIZE * sizeof(struct pollfd)); + if (!pfp) + return False; + pfp[0].fd = dpy->fd; + pfp[0].events = POLLIN; + + dpy->filedes = (XPointer)pfp; +#endif + return True; +} + +void _XPollfdCacheAdd(dpy, fd) + Display *dpy; + int fd; +{ +#ifdef USE_POLL + struct pollfd *pfp = (struct pollfd *)dpy->filedes; + + if (dpy->im_fd_length <= POLLFD_CACHE_SIZE) { + pfp[dpy->im_fd_length].fd = fd; + pfp[dpy->im_fd_length].events = POLLIN; + } +#endif +} + +/* ARGSUSED */ +void _XPollfdCacheDel(dpy, fd) + Display *dpy; + int fd; /* not used */ +{ +#ifdef USE_POLL + struct pollfd *pfp = (struct pollfd *)dpy->filedes; + struct _XConnectionInfo *conni; + + /* just recalculate whole list */ + if (dpy->im_fd_length <= POLLFD_CACHE_SIZE) { + int loc = 1; + for (conni = dpy->im_fd_info; conni; conni=conni->next) { + pfp[loc].fd = conni->fd; + pfp[loc].events = POLLIN; + loc++; + } + } +#endif +} + +/* returns True iff there is an event in the queue newer than serial_num */ + +static Bool +_XNewerQueuedEvent(dpy, serial_num) + Display *dpy; + int serial_num; +{ + _XQEvent *qev; + + if (dpy->next_event_serial_num == serial_num) + return False; + + qev = dpy->head; + while (qev) { + if (qev->qserial_num >= serial_num) { + return True; + } + qev = qev->next; + } + return False; +} + +static int +_XWaitForReadable(dpy) + Display *dpy; +{ + int result; + int fd = dpy->fd; + struct _XConnectionInfo *ilist; + register int saved_event_serial; + int in_read_events; + register Bool did_proc_conni = False; +#ifdef USE_POLL + struct pollfd *filedes; +#else + fd_set r_mask; + int highest_fd = fd; +#endif + +#ifdef USE_POLL + if (dpy->im_fd_length + 1 > POLLFD_CACHE_SIZE + && !(dpy->flags & XlibDisplayProcConni)) { + /* XXX - this fallback is gross */ + int i; + + filedes = (struct pollfd *)Xmalloc(dpy->im_fd_length * sizeof(struct pollfd)); + filedes[0].fd = fd; + filedes[0].events = POLLIN; + for (ilist=dpy->im_fd_info, i=1; ilist; ilist=ilist->next, i++) { + filedes[i].fd = ilist->fd; + filedes[i].events = POLLIN; + } + } else { + filedes = (struct pollfd *)dpy->filedes; + } +#else + FD_ZERO(&r_mask); +#endif + for (;;) { +#ifndef USE_POLL + FD_SET(fd, &r_mask); + if (!(dpy->flags & XlibDisplayProcConni)) + for (ilist=dpy->im_fd_info; ilist; ilist=ilist->next) { + FD_SET(ilist->fd, &r_mask); + if (ilist->fd > highest_fd) + highest_fd = ilist->fd; + } +#endif + UnlockDisplay(dpy); +#ifdef USE_POLL + result = poll(filedes, + (dpy->flags & XlibDisplayProcConni) ? 1 : 1+dpy->im_fd_length, + -1); +#else + result = Select(highest_fd + 1, &r_mask, NULL, NULL, NULL); +#endif + InternalLockDisplay(dpy, dpy->flags & XlibDisplayReply); + if (result == -1 && !ECHECK(EINTR)) _XIOError(dpy); + if (result <= 0) + continue; +#ifdef USE_POLL + if (filedes[0].revents & (POLLIN|POLLHUP|POLLERR)) +#else + if (FD_ISSET(fd, &r_mask)) +#endif + break; + if (!(dpy->flags & XlibDisplayProcConni)) { + int i; + + saved_event_serial = dpy->next_event_serial_num; + /* dpy flags can be clobbered by internal connection callback */ + in_read_events = dpy->flags & XlibDisplayReadEvents; + for (ilist=dpy->im_fd_info, i=1; ilist; ilist=ilist->next, i++) { +#ifdef USE_POLL + if (filedes[i].revents & POLLIN) +#else + if (FD_ISSET(ilist->fd, &r_mask)) +#endif + { + _XProcessInternalConnection(dpy, ilist); + did_proc_conni = True; + } + } +#ifdef USE_POLL + if (dpy->im_fd_length + 1 > POLLFD_CACHE_SIZE) + Xfree(filedes); +#endif + } + if (did_proc_conni) { + /* some internal connection callback might have done an + XPutBackEvent. We notice it here and if we needed an event, + we can return all the way. */ + if (_XNewerQueuedEvent(dpy, saved_event_serial) + && (in_read_events +#ifdef XTHREADS + || (dpy->lock && dpy->lock->event_awaiters) +#endif + )) + return -2; + did_proc_conni = False; + } + } +#ifdef XTHREADS +#ifdef XTHREADS_DEBUG + printf("thread %x _XWaitForReadable returning\n", XThread_Self()); +#endif +#endif + return 0; +} + +static +int _XSeqSyncFunction(dpy) + register Display *dpy; +{ + xGetInputFocusReply rep; + register xReq *req; + + LockDisplay(dpy); + if ((dpy->request - dpy->last_request_read) >= (BUFSIZE / SIZEOF(xReq))) { + GetEmptyReq(GetInputFocus, req); + (void) _XReply (dpy, (xReply *)&rep, 0, xTrue); + } + /* could get XID handler while waiting for reply in MT env */ + if (dpy->synchandler == _XSeqSyncFunction) { + dpy->synchandler = dpy->savedsynchandler; + dpy->flags &= ~XlibDisplayPrivSync; + } + UnlockDisplay(dpy); + SyncHandle(); + return 0; +} + +#ifdef XTHREADS +static void _XFlushInt(); +#endif + +/* + * _XFlush - Flush the X request buffer. If the buffer is empty, no + * action is taken. This routine correctly handles incremental writes. + * This routine may have to be reworked if int < long. + */ +void _XFlush (dpy) + register Display *dpy; +{ +#ifdef XTHREADS + /* With multi-threading we introduce an internal routine to which + we can pass a condition variable to do locking correctly. */ + + _XFlushInt(dpy, NULL); +} + +/* _XFlushInt - Internal version of _XFlush used to do multi-threaded + * locking correctly. + */ + +static void _XFlushInt (dpy, cv) + register Display *dpy; + register xcondition_t cv; +{ + char *nextindex; +#endif /* XTHREADS*/ + register long size, todo; + register int write_stat; + register char *bufindex; + _XExtension *ext; + + /* This fix resets the bufptr to the front of the buffer so + * additional appends to the bufptr will not corrupt memory. Since + * the server is down, these appends are no-op's anyway but + * callers of _XFlush() are not verifying this before they call it. + */ + if (dpy->flags & XlibDisplayIOError) + { + dpy->bufptr = dpy->buffer; + dpy->last_req = (char *)&_dummy_request; + return; + } + +#ifdef XTHREADS + while (dpy->flags & XlibDisplayWriting) { + ConditionWait(dpy, dpy->lock->writers); + } +#endif + size = todo = dpy->bufptr - dpy->buffer; + if (!size) return; +#ifdef XTHREADS + dpy->flags |= XlibDisplayWriting; + /* make sure no one else can put in data */ + dpy->bufptr = dpy->bufmax; +#endif + for (ext = dpy->flushes; ext; ext = ext->next_flush) + (*ext->before_flush)(dpy, &ext->codes, dpy->buffer, size); + bufindex = dpy->buffer; + /* + * While write has not written the entire buffer, keep looping + * until the entire buffer is written. bufindex will be + * incremented and size decremented as buffer is written out. + */ + while (size) { + ESET(0); + write_stat = _X11TransWrite(dpy->trans_conn, + bufindex, (int) todo); + if (write_stat >= 0) { + size -= write_stat; + todo = size; + bufindex += write_stat; + } else if (ETEST()) { + _XWaitForWritable(dpy +#ifdef XTHREADS + , cv +#endif + ); +#ifdef SUNSYSV + } else if (ECHECK(0)) { + _XWaitForWritable(dpy +#ifdef XTHREADS + , cv +#endif + ); +#endif +#ifdef ESZTEST + } else if (ESZTEST()) { + if (todo > 1) + todo >>= 1; + else { + _XWaitForWritable(dpy +#ifdef XTHREADS + , cv +#endif + ); + } +#endif + } else if (!ECHECK(EINTR)) { + /* Write failed! */ + /* errno set by write system call. */ + _XIOError(dpy); + } + } + dpy->last_req = (char *)&_dummy_request; + if ((dpy->request - dpy->last_request_read) >= SEQLIMIT && + !(dpy->flags & XlibDisplayPrivSync)) { + dpy->savedsynchandler = dpy->synchandler; + dpy->synchandler = _XSeqSyncFunction; + dpy->flags |= XlibDisplayPrivSync; + } + dpy->bufptr = dpy->buffer; +#ifdef XTHREADS + dpy->flags &= ~XlibDisplayWriting; +#endif +} + +int +_XEventsQueued (dpy, mode) + register Display *dpy; + int mode; +{ + register BytesReadable_t len; + BytesReadable_t pend; + _XAlignedBuffer buf; + register xReply *rep; + char *read_buf; +#ifdef XTHREADS + int entry_event_serial_num; + struct _XCVList *cvl = NULL; + xthread_t self; + +#ifdef XTHREADS_DEBUG + printf("_XEventsQueued called in thread %x\n", XThread_Self()); +#endif +#endif /* XTHREADS*/ + + if (mode == QueuedAfterFlush) + { + _XFlush(dpy); + if (dpy->qlen) + return(dpy->qlen); + } + if (dpy->flags & XlibDisplayIOError) return(dpy->qlen); + +#ifdef XTHREADS + /* create our condition variable and append to list, + * unless we were called from within XProcessInternalConnection + * or XLockDisplay + */ + xthread_clear_id(self); + if (dpy->lock && (xthread_have_id (dpy->lock->conni_thread) + || xthread_have_id (dpy->lock->locking_thread))) + /* some thread is in XProcessInternalConnection or XLockDisplay + so we have to see if we are it */ + self = XThread_Self(); + if (!xthread_have_id(self) + || (!xthread_equal(self, dpy->lock->conni_thread) + && !xthread_equal(self, dpy->lock->locking_thread))) { + /* In the multi-threaded case, if there is someone else + reading events, then there aren't any available, so + we just return. If we waited we would block. + */ + if (dpy->lock && dpy->lock->event_awaiters) + return dpy->qlen; + /* nobody here but us, so lock out any newcomers */ + cvl = QueueEventReaderLock(dpy); + } + + while (dpy->lock && cvl && dpy->lock->reply_first) { + /* note which events we have already seen so we'll know + if _XReply (in another thread) reads one */ + entry_event_serial_num = dpy->next_event_serial_num; + ConditionWait(dpy, cvl->cv); + /* did _XReply read an event we can return? */ + if (_XNewerQueuedEvent(dpy, entry_event_serial_num)) + { + UnlockNextEventReader(dpy); + return 0; + } + } +#endif /* XTHREADS*/ + + if (_X11TransBytesReadable(dpy->trans_conn, &pend) < 0) + _XIOError(dpy); +#ifdef XCONN_CHECK_FREQ + /* This is a crock, required because FIONREAD or equivalent is + * not guaranteed to detect a broken connection. + */ + if (!pend && !dpy->qlen && ++dpy->conn_checker >= XCONN_CHECK_FREQ) + { +#ifdef USE_POLL + struct pollfd filedes; +#else + fd_set r_mask; + static struct timeval zero_time; +#endif + + dpy->conn_checker = 0; +#ifdef USE_POLL + filedes.fd = dpy->fd; + filedes.events = POLLIN; + if ((pend = poll(&filedes, 1, 0))) +#else + FD_ZERO(&r_mask); + FD_SET(dpy->fd, &r_mask); + if ((pend = Select(dpy->fd + 1, &r_mask, NULL, NULL, &zero_time))) +#endif + { + if (pend > 0) + { + if (_X11TransBytesReadable(dpy->trans_conn, &pend) < 0) + _XIOError(dpy); + /* we should not get zero, if we do, force a read */ + if (!pend) + pend = SIZEOF(xReply); + } + else if (pend < 0 && !ECHECK(EINTR)) + _XIOError(dpy); + } + } +#endif /* XCONN_CHECK_FREQ */ + if (!(len = pend)) { + /* _XFlush can enqueue events */ + UnlockNextEventReader(dpy); + return(dpy->qlen); + } + /* Force a read if there is not enough data. Otherwise, + * a select() loop at a higher-level will spin undesirably, + * and we've seen at least one OS that appears to not update + * the result from FIONREAD once it has returned nonzero. + */ +#ifdef XTHREADS + if (dpy->lock && dpy->lock->reply_awaiters) { + read_buf = (char *)dpy->lock->reply_awaiters->buf; + len = SIZEOF(xReply); + } else +#endif /* XTHREADS*/ + { + read_buf = buf.buf; + + if (len < SIZEOF(xReply) +#ifdef XTHREADS + || dpy->async_handlers +#endif + ) + len = SIZEOF(xReply); + else if (len > BUFSIZE) + len = BUFSIZE; + len = (len / SIZEOF(xReply)) * SIZEOF(xReply); + } +#ifdef XCONN_CHECK_FREQ + dpy->conn_checker = 0; +#endif + + (void) _XRead (dpy, read_buf, (long) len); + +#ifdef XTHREADS + /* what did we actually read: reply or event? */ + if (dpy->lock && dpy->lock->reply_awaiters) { + if (((xReply *)read_buf)->generic.type == X_Reply || + ((xReply *)read_buf)->generic.type == X_Error) + { + dpy->lock->reply_was_read = True; + dpy->lock->reply_first = True; + if (read_buf != (char *)dpy->lock->reply_awaiters->buf) + memcpy(dpy->lock->reply_awaiters->buf, read_buf, + len); + UnlockNextEventReader(dpy); + return(dpy->qlen); /* we read, so we can return */ + } else if (read_buf != buf.buf) + memcpy(buf.buf, read_buf, len); + } +#endif /* XTHREADS*/ + + STARTITERATE(rep,xReply,buf.buf,len > 0) { + if (rep->generic.type == X_Reply) { + pend = len; + RESETITERPTR(rep,xReply, + _XAsyncReply (dpy, rep, + ITERPTR(rep), &pend, True)); + len = pend; + } else { + if (rep->generic.type == X_Error) + _XError (dpy, (xError *)rep); + else /* must be an event packet */ + _XEnq (dpy, (xEvent *)rep); + INCITERPTR(rep,xReply); + len -= SIZEOF(xReply); + } + } ENDITERATE + + UnlockNextEventReader(dpy); + return(dpy->qlen); +} + +/* _XReadEvents - Flush the output queue, + * then read as many events as possible (but at least 1) and enqueue them + */ +void _XReadEvents(dpy) + register Display *dpy; +{ + _XAlignedBuffer buf; + BytesReadable_t pend; + register BytesReadable_t len; + register xReply *rep; + Bool not_yet_flushed = True; + char *read_buf; + int i; + int entry_event_serial_num = dpy->next_event_serial_num; +#ifdef XTHREADS + struct _XCVList *cvl = NULL; + xthread_t self; + +#ifdef XTHREADS_DEBUG + printf("_XReadEvents called in thread %x\n", + XThread_Self()); +#endif + /* create our condition variable and append to list, + * unless we were called from within XProcessInternalConnection + * or XLockDisplay + */ + xthread_clear_id(self); + if (dpy->lock && (xthread_have_id (dpy->lock->conni_thread) + || xthread_have_id (dpy->lock->locking_thread))) + /* some thread is in XProcessInternalConnection or XLockDisplay + so we have to see if we are it */ + self = XThread_Self(); + if (!xthread_have_id(self) + || (!xthread_equal(self, dpy->lock->conni_thread) + && !xthread_equal(self, dpy->lock->locking_thread))) + cvl = QueueEventReaderLock(dpy); +#endif /* XTHREADS */ + + do { +#ifdef XTHREADS + /* if it is not our turn to read an event off the wire, + wait til we're at head of list */ + if (dpy->lock && cvl && + (dpy->lock->event_awaiters != cvl || + dpy->lock->reply_first)) { + ConditionWait(dpy, cvl->cv); + continue; + } +#endif /* XTHREADS */ + /* find out how much data can be read */ + if (_X11TransBytesReadable(dpy->trans_conn, &pend) < 0) + _XIOError(dpy); + len = pend; + + /* must read at least one xEvent; if none is pending, then + we'll just flush and block waiting for it */ + if (len < SIZEOF(xEvent) +#ifdef XTHREADS + || dpy->async_handlers +#endif + ) { + len = SIZEOF(xEvent); + /* don't flush until the first time we would block */ + if (not_yet_flushed) { + _XFlush (dpy); + if (_XNewerQueuedEvent(dpy, entry_event_serial_num)) { + /* _XReply has read an event for us */ + goto got_event; + } + not_yet_flushed = False; + } + } + +#ifdef XTHREADS + /* If someone is waiting for a reply, gamble that + the reply will be the next thing on the wire + and read it into their buffer. */ + if (dpy->lock && dpy->lock->reply_awaiters) { + read_buf = (char *)dpy->lock->reply_awaiters->buf; + len = SIZEOF(xReply); + } else +#endif /* XTHREADS*/ + { + read_buf = buf.buf; + + /* but we won't read more than the max buffer size */ + if (len > BUFSIZE) + len = BUFSIZE; + + /* round down to an integral number of XReps */ + len = (len / SIZEOF(xEvent)) * SIZEOF(xEvent); + } + +#ifdef XTHREADS + if (xthread_have_id(self)) + /* save value we may have to stick in conni_thread */ + dpy->lock->reading_thread = self; +#endif /* XTHREADS */ + dpy->flags |= XlibDisplayReadEvents; + i = _XRead (dpy, read_buf, (long) len); + dpy->flags &= ~XlibDisplayReadEvents; + if (i == -2) { + /* special flag from _XRead to say that internal connection has + done XPutBackEvent. Which we can use so we're done. */ + got_event: +#ifdef XTHREADS + if (dpy->lock && dpy->lock->lock_wait) { + if (dpy->lock->event_awaiters != cvl) + /* since it is not us, must be user lock thread */ + ConditionSignal(dpy, + dpy->lock->event_awaiters->cv); + (*dpy->lock->lock_wait)(dpy); + continue; + } +#endif + break; + } +#ifdef XTHREADS + if (xthread_have_id(self)) + xthread_clear_id(dpy->lock->reading_thread); + + /* what did we actually read: reply or event? */ + if (dpy->lock && dpy->lock->reply_awaiters) { + if (((xReply *)read_buf)->generic.type == X_Reply || + ((xReply *)read_buf)->generic.type == X_Error) + { + dpy->lock->reply_was_read = True; + dpy->lock->reply_first = True; + if (read_buf != (char *)dpy->lock->reply_awaiters->buf) + memcpy(dpy->lock->reply_awaiters->buf, + read_buf, len); + ConditionSignal(dpy, dpy->lock->reply_awaiters->cv); + continue; + } else if (read_buf != buf.buf) + memcpy(buf.buf, read_buf, len); + } +#endif /* XTHREADS */ + + STARTITERATE(rep,xReply,buf.buf,len > 0) { + if (rep->generic.type == X_Reply) { + pend = len; + RESETITERPTR(rep,xReply, + _XAsyncReply (dpy, rep, + ITERPTR(rep), &pend, True)); + len = pend; + } else { + if (rep->generic.type == X_Error) + _XError (dpy, (xError *) rep); + else /* must be an event packet */ + _XEnq (dpy, (xEvent *)rep); + INCITERPTR(rep,xReply); + len -= SIZEOF(xReply); + } + } ENDITERATE; + } while (!_XNewerQueuedEvent(dpy, entry_event_serial_num)); + + UnlockNextEventReader(dpy); +} + +/* + * _XRead - Read bytes from the socket taking into account incomplete + * reads. This routine may have to be reworked if int < long. + */ +int _XRead (dpy, data, size) + register Display *dpy; + register char *data; + register long size; +{ + register long bytes_read; +#ifdef XTHREADS + int original_size = size; +#endif + + if ((dpy->flags & XlibDisplayIOError) || size == 0) + return 0; + ESET(0); + while ((bytes_read = _X11TransRead(dpy->trans_conn, data, (int)size)) + != size) { + + if (bytes_read > 0) { + size -= bytes_read; + data += bytes_read; + } + else if (ETEST()) { + if (_XWaitForReadable(dpy) == -2) + return -2; /* internal connection did XPutBackEvent */ + ESET(0); + } +#ifdef SUNSYSV + else if (ECHECK(0)) { + if (_XWaitForReadable(dpy) == -2) + return -2; /* internal connection did XPutBackEvent */ + } +#endif + else if (bytes_read == 0) { + /* Read failed because of end of file! */ + ESET(EPIPE); + _XIOError(dpy); + } + + else /* bytes_read is less than 0; presumably -1 */ { + /* If it's a system call interrupt, it's not an error. */ + if (!ECHECK(EINTR)) + _XIOError(dpy); + } + } +#ifdef XTHREADS + if (dpy->lock && dpy->lock->reply_bytes_left > 0) + { + dpy->lock->reply_bytes_left -= original_size; + if (dpy->lock->reply_bytes_left == 0) { + dpy->flags &= ~XlibDisplayReply; + UnlockNextReplyReader(dpy); + } + } +#endif /* XTHREADS*/ + return 0; +} + +#ifdef LONG64 +void _XRead32 (dpy, data, len) + Display *dpy; + register long *data; + long len; +{ + register int *buf; + register long i; + + if (len) { + (void) _XRead(dpy, (char *)data, len); + i = len >> 2; + buf = (int *)data + i; + data += i; + while (--i >= 0) + *--data = *--buf; + } +} +#endif /* LONG64 */ + +#ifdef WORD64 + +/* + * XXX This is a *really* stupid way of doing this.... + * PACKBUFFERSIZE must be a multiple of 4. + */ + +#define PACKBUFFERSIZE 4096 + + +/* + * _XRead32 - Read bytes from the socket unpacking each 32 bits + * into a long (64 bits on a CRAY computer). + * + */ +static void _doXRead32 (dpy, data, size, packbuffer) + register Display *dpy; + register long *data; + register long size; + register char *packbuffer; +{ + long *lpack,*lp; + long mask32 = 0x00000000ffffffff; + long maskw, nwords, i, bits; + + _XReadPad (dpy, packbuffer, size); + + lp = data; + lpack = (long *) packbuffer; + nwords = size >> 2; + bits = 32; + + for(i=0;i<nwords;i++){ + maskw = mask32 << bits; + *lp++ = ( *lpack & maskw ) >> bits; + bits = bits ^32; + if(bits){ + lpack++; + } + } +} + +void _XRead32 (dpy, data, len) + Display *dpy; + long *data; + long len; +{ + char packbuffer[PACKBUFFERSIZE]; + unsigned nunits = PACKBUFFERSIZE >> 2; + + for (; len > PACKBUFFERSIZE; len -= PACKBUFFERSIZE, data += nunits) { + _doXRead32 (dpy, data, PACKBUFFERSIZE, packbuffer); + } + if (len) _doXRead32 (dpy, data, len, packbuffer); +} + + + +/* + * _XRead16 - Read bytes from the socket unpacking each 16 bits + * into a long (64 bits on a CRAY computer). + * + */ +static _doXRead16 (dpy, data, size, packbuffer) + register Display *dpy; + register short *data; + register long size; + char *packbuffer; +{ + long *lpack,*lp; + long mask16 = 0x000000000000ffff; + long maskw, nwords, i, bits; + + (void) _XRead(dpy,packbuffer,size); /* don't do a padded read... */ + + lp = (long *) data; + lpack = (long *) packbuffer; + nwords = size >> 1; /* number of 16 bit words to be unpacked */ + bits = 48; + for(i=0;i<nwords;i++){ + maskw = mask16 << bits; + *lp++ = ( *lpack & maskw ) >> bits; + bits -= 16; + if(bits < 0){ + lpack++; + bits = 48; + } + } +} + +void _XRead16 (dpy, data, len) + Display *dpy; + short *data; + long len; +{ + char packbuffer[PACKBUFFERSIZE]; + unsigned nunits = PACKBUFFERSIZE >> 1; + + for (; len > PACKBUFFERSIZE; len -= PACKBUFFERSIZE, data += nunits) { + _doXRead16 (dpy, data, PACKBUFFERSIZE, packbuffer); + } + if (len) _doXRead16 (dpy, data, len, packbuffer); +} + +void _XRead16Pad (dpy, data, size) + Display *dpy; + short *data; + long size; +{ + int slop = (size & 3); + short slopbuf[3]; + + _XRead16 (dpy, data, size); + if (slop > 0) { + _XRead16 (dpy, slopbuf, 4 - slop); + } +} +#endif /* WORD64 */ + + +/* + * _XReadPad - Read bytes from the socket taking into account incomplete + * reads. If the number of bytes is not 0 mod 4, read additional pad + * bytes. This routine may have to be reworked if int < long. + */ +void _XReadPad (dpy, data, size) + register Display *dpy; + register char *data; + register long size; +{ + register long bytes_read; + struct iovec iov[2]; + char pad[3]; +#ifdef XTHREADS + int original_size; +#endif + + if ((dpy->flags & XlibDisplayIOError) || size == 0) return; + iov[0].iov_len = (int)size; + iov[0].iov_base = data; + /* + * The following hack is used to provide 32 bit long-word + * aligned padding. The [1] vector is of length 0, 1, 2, or 3, + * whatever is needed. + */ + + iov[1].iov_len = padlength[size & 3]; + iov[1].iov_base = pad; + size += iov[1].iov_len; +#ifdef XTHREADS + original_size = size; +#endif + ESET(0); + while ((bytes_read = _X11TransReadv (dpy->trans_conn, iov, 2)) != size) { + + if (bytes_read > 0) { + size -= bytes_read; + if ((iov[0].iov_len -= bytes_read) < 0) { + iov[1].iov_len += iov[0].iov_len; + iov[1].iov_base = (char *)iov[1].iov_base - iov[0].iov_len; + iov[0].iov_len = 0; + } + else + iov[0].iov_base = (char *)iov[0].iov_base + bytes_read; + } + else if (ETEST()) { + _XWaitForReadable(dpy); + ESET(0); + } +#ifdef SUNSYSV + else if (ECHECK(0)) { + _XWaitForReadable(dpy); + } +#endif + else if (bytes_read == 0) { + /* Read failed because of end of file! */ + ESET(EPIPE); + _XIOError(dpy); + } + + else /* bytes_read is less than 0; presumably -1 */ { + /* If it's a system call interrupt, it's not an error. */ + if (!ECHECK(EINTR)) + _XIOError(dpy); + } + } +#ifdef XTHREADS + if (dpy->lock && dpy->lock->reply_bytes_left > 0) + { + dpy->lock->reply_bytes_left -= original_size; + if (dpy->lock->reply_bytes_left == 0) { + dpy->flags &= ~XlibDisplayReply; + UnlockNextReplyReader(dpy); + } + } +#endif /* XTHREADS*/ +} + +/* + * _XSend - Flush the buffer and send the client data. 32 bit word aligned + * transmission is used, if size is not 0 mod 4, extra bytes are transmitted. + * This routine may have to be reworked if int < long; + */ +void +#if NeedFunctionPrototypes +_XSend ( + register Display *dpy, + _Xconst char *data, + register long size) +#else +_XSend (dpy, data, size) + register Display *dpy; + char *data; + register long size; +#endif +{ + struct iovec iov[3]; + static char pad[3] = {0, 0, 0}; + /* XText8 and XText16 require that the padding bytes be zero! */ + + long skip, dbufsize, padsize, total, todo; + _XExtension *ext; + + if (!size || (dpy->flags & XlibDisplayIOError)) return; + dbufsize = dpy->bufptr - dpy->buffer; +#ifdef XTHREADS + dpy->flags |= XlibDisplayWriting; + /* make sure no one else can put in data */ + dpy->bufptr = dpy->bufmax; +#endif + padsize = padlength[size & 3]; + for (ext = dpy->flushes; ext; ext = ext->next_flush) { + (*ext->before_flush)(dpy, &ext->codes, dpy->buffer, dbufsize); + (*ext->before_flush)(dpy, &ext->codes, (char *)data, size); + if (padsize) + (*ext->before_flush)(dpy, &ext->codes, pad, padsize); + } + skip = 0; + todo = total = dbufsize + size + padsize; + + /* + * There are 3 pieces that may need to be written out: + * + * o whatever is in the display buffer + * o the data passed in by the user + * o any padding needed to 32bit align the whole mess + * + * This loop looks at all 3 pieces each time through. It uses skip + * to figure out whether or not a given piece is needed. + */ + while (total) { + long before = skip; /* amount of whole thing written */ + long remain = todo; /* amount to try this time, <= total */ + int i = 0; + long len; + + /* You could be very general here and have "in" and "out" iovecs + * and write a loop without using a macro, but what the heck. This + * translates to: + * + * how much of this piece is new? + * if more new then we are trying this time, clamp + * if nothing new + * then bump down amount already written, for next piece + * else put new stuff in iovec, will need all of next piece + * + * Note that todo had better be at least 1 or else we'll end up + * writing 0 iovecs. + */ +#define InsertIOV(pointer, length) \ + len = (length) - before; \ + if (len > remain) \ + len = remain; \ + if (len <= 0) { \ + before = (-len); \ + } else { \ + iov[i].iov_len = len; \ + iov[i].iov_base = (pointer) + before; \ + i++; \ + remain -= len; \ + before = 0; \ + } + + InsertIOV (dpy->buffer, dbufsize) + InsertIOV ((char *)data, size) + InsertIOV (pad, padsize) + + ESET(0); + if ((len = _X11TransWritev(dpy->trans_conn, iov, i)) >= 0) { + skip += len; + total -= len; + todo = total; + } else if (ETEST()) { + _XWaitForWritable(dpy +#ifdef XTHREADS + , NULL +#endif + ); +#ifdef SUNSYSV + } else if (ECHECK(0)) { + _XWaitForWritable(dpy +#ifdef XTHREADS + , NULL +#endif + ); +#endif +#ifdef ESZTEST + } else if (ESZTEST()) { + if (todo > 1) + todo >>= 1; + else { + _XWaitForWritable(dpy +#ifdef XTHREADS + , NULL +#endif + ); + } +#endif + } else if (!ECHECK(EINTR)) { + _XIOError(dpy); + } + } + dpy->last_req = (char *) & _dummy_request; + if ((dpy->request - dpy->last_request_read) >= SEQLIMIT && + !(dpy->flags & XlibDisplayPrivSync)) { + dpy->savedsynchandler = dpy->synchandler; + dpy->synchandler = _XSeqSyncFunction; + dpy->flags |= XlibDisplayPrivSync; + } + dpy->bufptr = dpy->buffer; +#ifdef XTHREADS + dpy->flags &= ~XlibDisplayWriting; +#endif + return; +} + +static void +_XGetMiscCode(dpy) + register Display *dpy; +{ + xQueryExtensionReply qrep; + register xQueryExtensionReq *qreq; + xXCMiscGetVersionReply vrep; + register xXCMiscGetVersionReq *vreq; + + if (dpy->xcmisc_opcode) + return; + GetReq(QueryExtension, qreq); + qreq->nbytes = sizeof(XCMiscExtensionName) - 1; + qreq->length += (qreq->nbytes+(unsigned)3)>>2; + _XSend(dpy, XCMiscExtensionName, (long)qreq->nbytes); + if (!_XReply (dpy, (xReply *)&qrep, 0, xTrue)) + dpy->xcmisc_opcode = -1; + else { + GetReq(XCMiscGetVersion, vreq); + vreq->reqType = qrep.major_opcode; + vreq->miscReqType = X_XCMiscGetVersion; + vreq->majorVersion = XCMiscMajorVersion; + vreq->minorVersion = XCMiscMinorVersion; + if (!_XReply (dpy, (xReply *)&vrep, 0, xTrue)) + dpy->xcmisc_opcode = -1; + else + dpy->xcmisc_opcode = qrep.major_opcode; + } +} + +static int +_XIDHandler(dpy) + register Display *dpy; +{ + xXCMiscGetXIDRangeReply grep; + register xXCMiscGetXIDRangeReq *greq; + + LockDisplay(dpy); + _XGetMiscCode(dpy); + if (dpy->xcmisc_opcode > 0) { + GetReq(XCMiscGetXIDRange, greq); + greq->reqType = dpy->xcmisc_opcode; + greq->miscReqType = X_XCMiscGetXIDRange; + if (_XReply (dpy, (xReply *)&grep, 0, xTrue) && grep.count) { + dpy->resource_id = ((grep.start_id - dpy->resource_base) >> + dpy->resource_shift); + dpy->resource_max = dpy->resource_id; + if (grep.count > 5) + dpy->resource_max += grep.count - 6; + dpy->resource_max <<= dpy->resource_shift; + } + } + if (dpy->flags & XlibDisplayPrivSync) { + dpy->synchandler = dpy->savedsynchandler; + dpy->flags &= ~XlibDisplayPrivSync; + } + UnlockDisplay(dpy); + SyncHandle(); + return 0; +} + +/* + * _XAllocID - resource ID allocation routine. + */ +XID _XAllocID(dpy) + register Display *dpy; +{ + XID id; + + id = dpy->resource_id << dpy->resource_shift; + if (id >= dpy->resource_max) { + if (!(dpy->flags & XlibDisplayPrivSync)) { + dpy->savedsynchandler = dpy->synchandler; + dpy->flags |= XlibDisplayPrivSync; + } + dpy->synchandler = _XIDHandler; + dpy->resource_max = dpy->resource_mask + 1; + } + if (id <= dpy->resource_mask) { + dpy->resource_id++; + return (dpy->resource_base + id); + } + if (id != 0x10000000) { + (void) fprintf(stderr, + "Xlib: resource ID allocation space exhausted!\n"); + id = 0x10000000; + dpy->resource_id = id >> dpy->resource_shift; + } + return id; +} + +/* + * _XAllocIDs - multiple resource ID allocation routine. + */ +void _XAllocIDs(dpy, ids, count) + register Display *dpy; + XID *ids; + int count; +{ + XID id; + int i; + xXCMiscGetXIDListReply grep; + register xXCMiscGetXIDListReq *greq; + + id = dpy->resource_id << dpy->resource_shift; + if (dpy->resource_max <= dpy->resource_mask && + id <= dpy->resource_mask && + (dpy->resource_max - id) > ((count - 1) << dpy->resource_shift)) { + id += dpy->resource_base; + for (i = 0; i < count; i++) { + ids[i] = id; + id += (1 << dpy->resource_shift); + dpy->resource_id++; + } + return; + } + grep.count = 0; + _XGetMiscCode(dpy); + if (dpy->xcmisc_opcode > 0) { + GetReq(XCMiscGetXIDList, greq); + greq->reqType = dpy->xcmisc_opcode; + greq->miscReqType = X_XCMiscGetXIDList; + greq->count = count; + if (_XReply(dpy, (xReply *)&grep, 0, xFalse) && grep.count) { + _XRead32(dpy, (long *) ids, 4L * (long) (grep.count)); + for (i = 0; i < grep.count; i++) { + id = (ids[i] - dpy->resource_base) >> dpy->resource_shift; + if (id >= dpy->resource_id) + dpy->resource_id = id; + } + if (id >= dpy->resource_max) { + if (!(dpy->flags & XlibDisplayPrivSync)) { + dpy->savedsynchandler = dpy->synchandler; + dpy->flags |= XlibDisplayPrivSync; + } + dpy->synchandler = _XIDHandler; + dpy->resource_max = dpy->resource_mask + 1; + } + } + } + for (i = grep.count; i < count; i++) + ids[i] = XAllocID(dpy); +} + +/* + * The hard part about this is that we only get 16 bits from a reply. + * We have three values that will march along, with the following invariant: + * dpy->last_request_read <= rep->sequenceNumber <= dpy->request + * We have to keep + * dpy->request - dpy->last_request_read < 2^16 + * or else we won't know for sure what value to use in events. We do this + * by forcing syncs when we get close. + */ + +unsigned long +_XSetLastRequestRead(dpy, rep) + register Display *dpy; + register xGenericReply *rep; +{ + register unsigned long newseq, lastseq; + + lastseq = dpy->last_request_read; + /* + * KeymapNotify has no sequence number, but is always guaranteed + * to immediately follow another event, except when generated via + * SendEvent (hmmm). + */ + if ((rep->type & 0x7f) == KeymapNotify) + return(lastseq); + + newseq = (lastseq & ~((unsigned long)0xffff)) | rep->sequenceNumber; + + if (newseq < lastseq) { + newseq += 0x10000; + if (newseq > dpy->request) { + (void) fprintf (stderr, + "Xlib: sequence lost (0x%lx > 0x%lx) in reply type 0x%x!\n", + newseq, dpy->request, + (unsigned int) rep->type); + newseq -= 0x10000; + } + } + + dpy->last_request_read = newseq; + return(newseq); +} + +/* + * _XReply - Wait for a reply packet and copy its contents into the + * specified rep. Meanwhile we must handle error and event packets that + * we may encounter. + */ +Status +_XReply (dpy, rep, extra, discard) + register Display *dpy; + register xReply *rep; + int extra; /* number of 32-bit words expected after the reply */ + Bool discard; /* should I discard data following "extra" words? */ +{ + /* Pull out the serial number now, so that (currently illegal) requests + * generated by an error handler don't confuse us. + */ + unsigned long cur_request = dpy->request; +#ifdef XTHREADS + struct _XCVList *cvl; +#endif + + if (dpy->flags & XlibDisplayIOError) + return 0; + +#ifdef XTHREADS + /* create our condition variable and append to list */ + cvl = QueueReplyReaderLock(dpy); + if (cvl) { + cvl->buf = rep; + if (dpy->lock->reply_awaiters == cvl && !dpy->lock->event_awaiters) + dpy->lock->reply_first = True; + } + +#ifdef XTHREADS_DEBUG + printf("_XReply called in thread %x, adding %x to cvl\n", + XThread_Self(), cvl); +#endif + + _XFlushInt(dpy, cvl ? cvl->cv : NULL); + /* if it is not our turn to read a reply off the wire, + * wait til we're at head of list. if there is an event waiter, + * and our reply hasn't been read, they'll be in select and will + * hand control back to us next. + */ + if(dpy->lock && + (dpy->lock->reply_awaiters != cvl || !dpy->lock->reply_first)) { + ConditionWait(dpy, cvl->cv); + } + dpy->flags |= XlibDisplayReply; +#else /* XTHREADS else */ + _XFlush(dpy); +#endif + + for (;;) { +#ifdef XTHREADS + /* Did another thread's _XReadEvents get our reply by accident? */ + if (!dpy->lock || !dpy->lock->reply_was_read) +#endif + (void) _XRead(dpy, (char *)rep, (long)SIZEOF(xReply)); +#ifdef XTHREADS + if (dpy->lock) + dpy->lock->reply_was_read = False; +#endif + + switch ((int)rep->generic.type) { + + case X_Reply: + /* Reply received. Fast update for synchronous replies, + * but deal with multiple outstanding replies. + */ + if (rep->generic.sequenceNumber == (cur_request & 0xffff)) + dpy->last_request_read = cur_request; + else { + int pend = SIZEOF(xReply); + if (_XAsyncReply(dpy, rep, (char *)rep, &pend, False) + != (char *)rep) + continue; + } + /* + * Don't accept ridiculously large values for + * generic.length; doing so could cause stack-scribbling + * problems elsewhere. + */ + if (rep->generic.length > GENERIC_LENGTH_LIMIT) { + rep->generic.length = GENERIC_LENGTH_LIMIT; + (void) fprintf(stderr, + "Xlib: suspiciously long reply length %d set to %d", + rep->generic.length, GENERIC_LENGTH_LIMIT); + } + if (extra <= rep->generic.length) { + if (extra > 0) + /* + * Read the extra data into storage immediately + * following the GenericReply structure. + */ + (void) _XRead (dpy, (char *) (NEXTPTR(rep,xReply)), + ((long)extra) << 2); + if (discard) { + if (extra < rep->generic.length) + _XEatData(dpy, (rep->generic.length - extra) << 2); + } +#ifdef XTHREADS + if (dpy->lock) { + if (discard) { + dpy->lock->reply_bytes_left = 0; + } else { + dpy->lock->reply_bytes_left = + (rep->generic.length - extra) << 2; + } + if (dpy->lock->reply_bytes_left == 0) { + dpy->flags &= ~XlibDisplayReply; + UnlockNextReplyReader(dpy); + } + } else + dpy->flags &= ~XlibDisplayReply; +#endif + return 1; + } + /* + *if we get here, then extra > rep->generic.length--meaning we + * read a reply that's shorter than we expected. This is an + * error, but we still need to figure out how to handle it... + */ + (void) _XRead (dpy, (char *) (NEXTPTR(rep,xReply)), + ((long) rep->generic.length) << 2); + dpy->flags &= ~XlibDisplayReply; + UnlockNextReplyReader(dpy); + _XIOError (dpy); + return (0); + + case X_Error: + { + register _XExtension *ext; + register Bool ret = False; + int ret_code; + xError *err = (xError *) rep; + unsigned long serial; + + dpy->flags &= ~XlibDisplayReply; + serial = _XSetLastRequestRead(dpy, (xGenericReply *)rep); + if (serial == cur_request) + /* do not die on "no such font", "can't allocate", + "can't grab" failures */ + switch ((int)err->errorCode) { + case BadName: + switch (err->majorCode) { + case X_LookupColor: + case X_AllocNamedColor: + UnlockNextReplyReader(dpy); + return(0); + } + break; + case BadFont: + if (err->majorCode == X_QueryFont) { + UnlockNextReplyReader(dpy); + return (0); + } + break; + case BadAlloc: + case BadAccess: + UnlockNextReplyReader(dpy); + return (0); + } + /* + * we better see if there is an extension who may + * want to suppress the error. + */ + for (ext = dpy->ext_procs; !ret && ext; ext = ext->next) { + if (ext->error) + ret = (*ext->error)(dpy, err, &ext->codes, &ret_code); + } + if (!ret) { + _XError(dpy, err); + ret_code = 0; + } + if (serial == cur_request) { + UnlockNextReplyReader(dpy); + return(ret_code); + } + + } /* case X_Error */ + break; + default: + _XEnq(dpy, (xEvent *) rep); +#ifdef XTHREADS + if (dpy->lock && dpy->lock->event_awaiters) + ConditionSignal(dpy, dpy->lock->event_awaiters->cv); +#endif + break; + } + } +} + +static char * +_XAsyncReply(dpy, rep, buf, lenp, discard) + Display *dpy; + register xReply *rep; + char *buf; + register int *lenp; + Bool discard; +{ + register _XAsyncHandler *async, *next; + register int len; + register Bool consumed = False; + char *nbuf; + + (void) _XSetLastRequestRead(dpy, &rep->generic); + len = SIZEOF(xReply) + (rep->generic.length << 2); + + for (async = dpy->async_handlers; async; async = next) { + next = async->next; + if ((consumed = (*async->handler)(dpy, rep, buf, *lenp, async->data))) + break; + } + if (!consumed) { + if (!discard) + return buf; + (void) fprintf(stderr, + "Xlib: unexpected async reply (sequence 0x%lx)!\n", + dpy->last_request_read); +#ifdef XTHREADS +#ifdef XTHREADS_DEBUG + printf("thread %x, unexpected async reply\n", XThread_Self()); +#endif +#endif + if (len > *lenp) + _XEatData(dpy, len - *lenp); + } + if (len < SIZEOF(xReply)) + { + ESET(EINVAL); + _XIOError (dpy); + buf += *lenp; + *lenp = 0; + return buf; + } + if (len >= *lenp) { + buf += *lenp; + *lenp = 0; + return buf; + } + *lenp -= len; + buf += len; + len = *lenp; + nbuf = buf; + while (len > SIZEOF(xReply)) { + if (*buf == X_Reply) + return nbuf; + buf += SIZEOF(xReply); + len -= SIZEOF(xReply); + } + if (len > 0 && len < SIZEOF(xReply)) { + buf = nbuf; + len = SIZEOF(xReply) - len; + nbuf -= len; + memmove(nbuf, buf, *lenp); + (void) _XRead(dpy, nbuf + *lenp, (long)len); + *lenp += len; + } + return nbuf; +} + +/* + * Support for internal connections, such as an IM might use. + * By Stephen Gildea, The Open Group, September 1993 + */ + +/* _XRegisterInternalConnection + * Each IM (or Xlib extension) that opens a file descriptor that Xlib should + * include in its select/poll mask must call this function to register the + * fd with Xlib. Any XConnectionWatchProc registered by XAddConnectionWatch + * will also be called. + * + * Whenever Xlib detects input available on fd, it will call callback + * with call_data to process it. If non-Xlib code calls select/poll + * and detects input available, it must call XProcessInternalConnection, + * which will call the associated callback. + * + * Non-Xlib code can learn about these additional fds by calling + * XInternalConnectionNumbers or, more typically, by registering + * a XConnectionWatchProc with XAddConnectionWatch + * to be called when fds are registered or unregistered. + * + * Returns True if registration succeeded, False if not, typically + * because could not allocate memory. + * Assumes Display locked when called. + */ +#if NeedFunctionPrototypes +Status _XRegisterInternalConnection( + Display* dpy, + int fd, + _XInternalConnectionProc callback, + XPointer call_data +) +#else +Status +_XRegisterInternalConnection(dpy, fd, callback, call_data) + Display *dpy; + int fd; + _XInternalConnectionProc callback; + XPointer call_data; +#endif +{ + struct _XConnectionInfo *new_conni, **iptr; + struct _XConnWatchInfo *watchers; + XPointer *wd; + + new_conni = (struct _XConnectionInfo*)Xmalloc(sizeof(struct _XConnectionInfo)); + if (!new_conni) + return 0; + new_conni->watch_data = (XPointer *)Xmalloc(dpy->watcher_count * sizeof(XPointer)); + if (!new_conni->watch_data) { + Xfree(new_conni); + return 0; + } + new_conni->fd = fd; + new_conni->read_callback = callback; + new_conni->call_data = call_data; + new_conni->next = NULL; + /* link new structure onto end of list */ + for (iptr = &dpy->im_fd_info; *iptr; iptr = &(*iptr)->next) + ; + *iptr = new_conni; + dpy->im_fd_length++; + _XPollfdCacheAdd(dpy, fd); + + for (watchers=dpy->conn_watchers, wd=new_conni->watch_data; + watchers; + watchers=watchers->next, wd++) { + *wd = NULL; /* for cleanliness */ + (*watchers->fn) (dpy, watchers->client_data, fd, True, wd); + } + + return 1; +} + +/* _XUnregisterInternalConnection + * Each IM (or Xlib extension) that closes a file descriptor previously + * registered with _XRegisterInternalConnection must call this function. + * Any XConnectionWatchProc registered by XAddConnectionWatch + * will also be called. + * + * Assumes Display locked when called. + */ +#if NeedFunctionPrototypes +void _XUnregisterInternalConnection( + Display* dpy, + int fd +) +#else +void +_XUnregisterInternalConnection(dpy, fd) + Display *dpy; + int fd; +#endif +{ + struct _XConnectionInfo *info_list, **prev; + struct _XConnWatchInfo *watch; + XPointer *wd; + + for (prev = &dpy->im_fd_info; (info_list = *prev); prev = &info_list->next) { + if (info_list->fd == fd) { + *prev = info_list->next; + dpy->im_fd_length--; + for (watch=dpy->conn_watchers, wd=info_list->watch_data; + watch; + watch=watch->next, wd++) { + (*watch->fn) (dpy, watch->client_data, fd, False, wd); + } + if (info_list->watch_data) + Xfree (info_list->watch_data); + Xfree (info_list); + break; + } + } + _XPollfdCacheDel(dpy, fd); +} + +/* XInternalConnectionNumbers + * Returns an array of fds and an array of corresponding call data. + * Typically a XConnectionWatchProc registered with XAddConnectionWatch + * will be used instead of this function to discover + * additional fds to include in the select/poll mask. + * + * The list is allocated with Xmalloc and should be freed by the caller + * with Xfree; + */ +#if NeedFunctionPrototypes +Status XInternalConnectionNumbers( + Display *dpy, + int **fd_return, + int *count_return +) +#else +Status +XInternalConnectionNumbers(dpy, fd_return, count_return) + Display *dpy; + int **fd_return; + int *count_return; +#endif +{ + int count; + struct _XConnectionInfo *info_list; + int *fd_list; + + LockDisplay(dpy); + count = 0; + for (info_list=dpy->im_fd_info; info_list; info_list=info_list->next) + count++; + fd_list = (int*) Xmalloc (count * sizeof(int)); + if (!fd_list) { + UnlockDisplay(dpy); + return 0; + } + count = 0; + for (info_list=dpy->im_fd_info; info_list; info_list=info_list->next) { + fd_list[count] = info_list->fd; + count++; + } + UnlockDisplay(dpy); + + *fd_return = fd_list; + *count_return = count; + return 1; +} + +static void _XProcessInternalConnection(dpy, conn_info) + Display *dpy; + struct _XConnectionInfo *conn_info; +{ + dpy->flags |= XlibDisplayProcConni; +#ifdef XTHREADS + if (dpy->lock) { + /* check cache to avoid call to thread_self */ + if (xthread_have_id(dpy->lock->reading_thread)) + dpy->lock->conni_thread = dpy->lock->reading_thread; + else + dpy->lock->conni_thread = XThread_Self(); + } +#endif /* XTHREADS */ + UnlockDisplay(dpy); + (*conn_info->read_callback) (dpy, conn_info->fd, conn_info->call_data); + LockDisplay(dpy); +#ifdef XTHREADS + if (dpy->lock) + xthread_clear_id(dpy->lock->conni_thread); +#endif /* XTHREADS */ + dpy->flags &= ~XlibDisplayProcConni; +} + +/* XProcessInternalConnection + * Call the _XInternalConnectionProc registered by _XRegisterInternalConnection + * for this fd. + * The Display is NOT locked during the call. + */ +#if NeedFunctionPrototypes +void XProcessInternalConnection( + Display* dpy, + int fd +) +#else +void +XProcessInternalConnection(dpy, fd) + Display *dpy; + int fd; +#endif +{ + struct _XConnectionInfo *info_list; + + LockDisplay(dpy); + for (info_list=dpy->im_fd_info; info_list; info_list=info_list->next) { + if (info_list->fd == fd) { + _XProcessInternalConnection(dpy, info_list); + break; + } + } + UnlockDisplay(dpy); +} + +/* XAddConnectionWatch + * Register a callback to be called whenever _XRegisterInternalConnection + * or _XUnregisterInternalConnection is called. + * Callbacks are called with the Display locked. + * If any connections are already registered, the callback is immediately + * called for each of them. + */ +#if NeedFunctionPrototypes +Status XAddConnectionWatch( + Display* dpy, + XConnectionWatchProc callback, + XPointer client_data +) +#else +Status +XAddConnectionWatch(dpy, callback, client_data) + Display *dpy; + XConnectionWatchProc callback; + XPointer client_data; +#endif +{ + struct _XConnWatchInfo *new_watcher, **wptr; + struct _XConnectionInfo *info_list; + XPointer *wd_array; + + LockDisplay(dpy); + + /* allocate new watch data */ + for (info_list=dpy->im_fd_info; info_list; info_list=info_list->next) { + wd_array = (XPointer *)Xrealloc((char *)info_list->watch_data, + (dpy->watcher_count + 1) * + sizeof(XPointer)); + if (!wd_array) { + UnlockDisplay(dpy); + return 0; + } + wd_array[dpy->watcher_count] = NULL; /* for cleanliness */ + } + + new_watcher = (struct _XConnWatchInfo*)Xmalloc(sizeof(struct _XConnWatchInfo)); + if (!new_watcher) { + UnlockDisplay(dpy); + return 0; + } + new_watcher->fn = callback; + new_watcher->client_data = client_data; + new_watcher->next = NULL; + + /* link new structure onto end of list */ + for (wptr = &dpy->conn_watchers; *wptr; wptr = &(*wptr)->next) + ; + *wptr = new_watcher; + dpy->watcher_count++; + + /* call new watcher on all currently registered fds */ + for (info_list=dpy->im_fd_info; info_list; info_list=info_list->next) { + (*callback) (dpy, client_data, info_list->fd, True, + info_list->watch_data + dpy->watcher_count - 1); + } + + UnlockDisplay(dpy); + return 1; +} + +/* XRemoveConnectionWatch + * Unregister a callback registered by XAddConnectionWatch. + * Both callback and client_data must match what was passed to + * XAddConnectionWatch. + */ +#if NeedFunctionPrototypes +void XRemoveConnectionWatch( + Display* dpy, + XConnectionWatchProc callback, + XPointer client_data +) +#else +void +XRemoveConnectionWatch(dpy, callback, client_data) + Display *dpy; + XConnectionWatchProc callback; + XPointer client_data; +#endif +{ + struct _XConnWatchInfo *watch; + struct _XConnWatchInfo *previous = NULL; + struct _XConnectionInfo *conni; + int counter = 0; + + LockDisplay(dpy); + for (watch=dpy->conn_watchers; watch; watch=watch->next) { + if (watch->fn == callback && watch->client_data == client_data) { + if (previous) + previous->next = watch->next; + else + dpy->conn_watchers = watch->next; + Xfree (watch); + dpy->watcher_count--; + /* remove our watch_data for each connection */ + for (conni=dpy->im_fd_info; conni; conni=conni->next) { + /* don't bother realloc'ing; these arrays are small anyway */ + /* overlapping */ + memmove(conni->watch_data+counter, + conni->watch_data+counter+1, + dpy->watcher_count - counter); + } + break; + } + previous = watch; + counter++; + } + UnlockDisplay(dpy); +} + +/* end of internal connections support */ + + +/* Read and discard "n" 8-bit bytes of data */ + +void _XEatData (dpy, n) + Display *dpy; + register unsigned long n; +{ +#define SCRATCHSIZE 2048 + char buf[SCRATCHSIZE]; + + while (n > 0) { + register long bytes_read = (n > SCRATCHSIZE) ? SCRATCHSIZE : n; + (void) _XRead (dpy, buf, bytes_read); + n -= bytes_read; + } +#undef SCRATCHSIZE +} + + +/* + * _XEnq - Place event packets on the display's queue. + * note that no squishing of move events in V11, since there + * is pointer motion hints.... + */ +void _XEnq (dpy, event) + register Display *dpy; + register xEvent *event; +{ + register _XQEvent *qelt; + + if ((qelt = dpy->qfree)) { + /* If dpy->qfree is non-NULL do this, else malloc a new one. */ + dpy->qfree = qelt->next; + } + else if ((qelt = + (_XQEvent *) Xmalloc((unsigned)sizeof(_XQEvent))) == NULL) { + /* Malloc call failed! */ + ESET(ENOMEM); + _XIOError(dpy); + } + qelt->next = NULL; + /* go call through display to find proper event reformatter */ + if ((*dpy->event_vec[event->u.u.type & 0177])(dpy, &qelt->event, event)) { + qelt->qserial_num = dpy->next_event_serial_num++; + if (dpy->tail) dpy->tail->next = qelt; + else dpy->head = qelt; + + dpy->tail = qelt; + dpy->qlen++; + } else { + /* ignored, or stashed away for many-to-one compression */ + qelt->next = dpy->qfree; + dpy->qfree = qelt; + } +} + +/* + * _XDeq - Remove event packet from the display's queue. + */ +void _XDeq (dpy, prev, qelt) + register Display *dpy; + register _XQEvent *prev; /* element before qelt */ + register _XQEvent *qelt; /* element to be unlinked */ +{ + if (prev) { + if ((prev->next = qelt->next) == NULL) + dpy->tail = prev; + } else { + /* no prev, so removing first elt */ + if ((dpy->head = qelt->next) == NULL) + dpy->tail = NULL; + } + qelt->qserial_num = 0; + qelt->next = dpy->qfree; + dpy->qfree = qelt; + dpy->qlen--; +} + +/* + * EventToWire in separate file in that often not needed. + */ + +/*ARGSUSED*/ +Bool +_XUnknownWireEvent(dpy, re, event) +register Display *dpy; /* pointer to display structure */ +register XEvent *re; /* pointer to where event should be reformatted */ +register xEvent *event; /* wire protocol event */ +{ +#ifdef notdef + (void) fprintf(stderr, + "Xlib: unhandled wire event! event number = %d, display = %x\n.", + event->u.u.type, dpy); +#endif + return(False); +} + +/*ARGSUSED*/ +Status +_XUnknownNativeEvent(dpy, re, event) +register Display *dpy; /* pointer to display structure */ +register XEvent *re; /* pointer to where event should be reformatted */ +register xEvent *event; /* wire protocol event */ +{ +#ifdef notdef + (void) fprintf(stderr, + "Xlib: unhandled native event! event number = %d, display = %x\n.", + re->type, dpy); +#endif + return(0); +} +/* + * reformat a wire event into an XEvent structure of the right type. + */ +Bool +_XWireToEvent(dpy, re, event) +register Display *dpy; /* pointer to display structure */ +register XEvent *re; /* pointer to where event should be reformatted */ +register xEvent *event; /* wire protocol event */ +{ + + re->type = event->u.u.type & 0x7f; + ((XAnyEvent *)re)->serial = _XSetLastRequestRead(dpy, + (xGenericReply *)event); + ((XAnyEvent *)re)->send_event = ((event->u.u.type & 0x80) != 0); + ((XAnyEvent *)re)->display = dpy; + + /* Ignore the leading bit of the event type since it is set when a + client sends an event rather than the server. */ + + switch (event-> u.u.type & 0177) { + case KeyPress: + case KeyRelease: + { + register XKeyEvent *ev = (XKeyEvent*) re; + ev->root = event->u.keyButtonPointer.root; + ev->window = event->u.keyButtonPointer.event; + ev->subwindow = event->u.keyButtonPointer.child; + ev->time = event->u.keyButtonPointer.time; + ev->x = cvtINT16toInt(event->u.keyButtonPointer.eventX); + ev->y = cvtINT16toInt(event->u.keyButtonPointer.eventY); + ev->x_root = cvtINT16toInt(event->u.keyButtonPointer.rootX); + ev->y_root = cvtINT16toInt(event->u.keyButtonPointer.rootY); + ev->state = event->u.keyButtonPointer.state; + ev->same_screen = event->u.keyButtonPointer.sameScreen; + ev->keycode = event->u.u.detail; + } + break; + case ButtonPress: + case ButtonRelease: + { + register XButtonEvent *ev = (XButtonEvent *) re; + ev->root = event->u.keyButtonPointer.root; + ev->window = event->u.keyButtonPointer.event; + ev->subwindow = event->u.keyButtonPointer.child; + ev->time = event->u.keyButtonPointer.time; + ev->x = cvtINT16toInt(event->u.keyButtonPointer.eventX); + ev->y = cvtINT16toInt(event->u.keyButtonPointer.eventY); + ev->x_root = cvtINT16toInt(event->u.keyButtonPointer.rootX); + ev->y_root = cvtINT16toInt(event->u.keyButtonPointer.rootY); + ev->state = event->u.keyButtonPointer.state; + ev->same_screen = event->u.keyButtonPointer.sameScreen; + ev->button = event->u.u.detail; + } + break; + case MotionNotify: + { + register XMotionEvent *ev = (XMotionEvent *)re; + ev->root = event->u.keyButtonPointer.root; + ev->window = event->u.keyButtonPointer.event; + ev->subwindow = event->u.keyButtonPointer.child; + ev->time = event->u.keyButtonPointer.time; + ev->x = cvtINT16toInt(event->u.keyButtonPointer.eventX); + ev->y = cvtINT16toInt(event->u.keyButtonPointer.eventY); + ev->x_root = cvtINT16toInt(event->u.keyButtonPointer.rootX); + ev->y_root = cvtINT16toInt(event->u.keyButtonPointer.rootY); + ev->state = event->u.keyButtonPointer.state; + ev->same_screen = event->u.keyButtonPointer.sameScreen; + ev->is_hint = event->u.u.detail; + } + break; + case EnterNotify: + case LeaveNotify: + { + register XCrossingEvent *ev = (XCrossingEvent *) re; + ev->root = event->u.enterLeave.root; + ev->window = event->u.enterLeave.event; + ev->subwindow = event->u.enterLeave.child; + ev->time = event->u.enterLeave.time; + ev->x = cvtINT16toInt(event->u.enterLeave.eventX); + ev->y = cvtINT16toInt(event->u.enterLeave.eventY); + ev->x_root = cvtINT16toInt(event->u.enterLeave.rootX); + ev->y_root = cvtINT16toInt(event->u.enterLeave.rootY); + ev->state = event->u.enterLeave.state; + ev->mode = event->u.enterLeave.mode; + ev->same_screen = (event->u.enterLeave.flags & + ELFlagSameScreen) && True; + ev->focus = (event->u.enterLeave.flags & + ELFlagFocus) && True; + ev->detail = event->u.u.detail; + } + break; + case FocusIn: + case FocusOut: + { + register XFocusChangeEvent *ev = (XFocusChangeEvent *) re; + ev->window = event->u.focus.window; + ev->mode = event->u.focus.mode; + ev->detail = event->u.u.detail; + } + break; + case KeymapNotify: + { + register XKeymapEvent *ev = (XKeymapEvent *) re; + ev->window = None; + memcpy(&ev->key_vector[1], + (char *)((xKeymapEvent *) event)->map, + sizeof (((xKeymapEvent *) event)->map)); + } + break; + case Expose: + { + register XExposeEvent *ev = (XExposeEvent *) re; + ev->window = event->u.expose.window; + ev->x = event->u.expose.x; + ev->y = event->u.expose.y; + ev->width = event->u.expose.width; + ev->height = event->u.expose.height; + ev->count = event->u.expose.count; + } + break; + case GraphicsExpose: + { + register XGraphicsExposeEvent *ev = + (XGraphicsExposeEvent *) re; + ev->drawable = event->u.graphicsExposure.drawable; + ev->x = event->u.graphicsExposure.x; + ev->y = event->u.graphicsExposure.y; + ev->width = event->u.graphicsExposure.width; + ev->height = event->u.graphicsExposure.height; + ev->count = event->u.graphicsExposure.count; + ev->major_code = event->u.graphicsExposure.majorEvent; + ev->minor_code = event->u.graphicsExposure.minorEvent; + } + break; + case NoExpose: + { + register XNoExposeEvent *ev = (XNoExposeEvent *) re; + ev->drawable = event->u.noExposure.drawable; + ev->major_code = event->u.noExposure.majorEvent; + ev->minor_code = event->u.noExposure.minorEvent; + } + break; + case VisibilityNotify: + { + register XVisibilityEvent *ev = (XVisibilityEvent *) re; + ev->window = event->u.visibility.window; + ev->state = event->u.visibility.state; + } + break; + case CreateNotify: + { + register XCreateWindowEvent *ev = + (XCreateWindowEvent *) re; + ev->window = event->u.createNotify.window; + ev->parent = event->u.createNotify.parent; + ev->x = cvtINT16toInt(event->u.createNotify.x); + ev->y = cvtINT16toInt(event->u.createNotify.y); + ev->width = event->u.createNotify.width; + ev->height = event->u.createNotify.height; + ev->border_width = event->u.createNotify.borderWidth; + ev->override_redirect = event->u.createNotify.override; + } + break; + case DestroyNotify: + { + register XDestroyWindowEvent *ev = + (XDestroyWindowEvent *) re; + ev->window = event->u.destroyNotify.window; + ev->event = event->u.destroyNotify.event; + } + break; + case UnmapNotify: + { + register XUnmapEvent *ev = (XUnmapEvent *) re; + ev->window = event->u.unmapNotify.window; + ev->event = event->u.unmapNotify.event; + ev->from_configure = event->u.unmapNotify.fromConfigure; + } + break; + case MapNotify: + { + register XMapEvent *ev = (XMapEvent *) re; + ev->window = event->u.mapNotify.window; + ev->event = event->u.mapNotify.event; + ev->override_redirect = event->u.mapNotify.override; + } + break; + case MapRequest: + { + register XMapRequestEvent *ev = (XMapRequestEvent *) re; + ev->window = event->u.mapRequest.window; + ev->parent = event->u.mapRequest.parent; + } + break; + case ReparentNotify: + { + register XReparentEvent *ev = (XReparentEvent *) re; + ev->event = event->u.reparent.event; + ev->window = event->u.reparent.window; + ev->parent = event->u.reparent.parent; + ev->x = cvtINT16toInt(event->u.reparent.x); + ev->y = cvtINT16toInt(event->u.reparent.y); + ev->override_redirect = event->u.reparent.override; + } + break; + case ConfigureNotify: + { + register XConfigureEvent *ev = (XConfigureEvent *) re; + ev->event = event->u.configureNotify.event; + ev->window = event->u.configureNotify.window; + ev->above = event->u.configureNotify.aboveSibling; + ev->x = cvtINT16toInt(event->u.configureNotify.x); + ev->y = cvtINT16toInt(event->u.configureNotify.y); + ev->width = event->u.configureNotify.width; + ev->height = event->u.configureNotify.height; + ev->border_width = event->u.configureNotify.borderWidth; + ev->override_redirect = event->u.configureNotify.override; + } + break; + case ConfigureRequest: + { + register XConfigureRequestEvent *ev = + (XConfigureRequestEvent *) re; + ev->window = event->u.configureRequest.window; + ev->parent = event->u.configureRequest.parent; + ev->above = event->u.configureRequest.sibling; + ev->x = cvtINT16toInt(event->u.configureRequest.x); + ev->y = cvtINT16toInt(event->u.configureRequest.y); + ev->width = event->u.configureRequest.width; + ev->height = event->u.configureRequest.height; + ev->border_width = event->u.configureRequest.borderWidth; + ev->value_mask = event->u.configureRequest.valueMask; + ev->detail = event->u.u.detail; + } + break; + case GravityNotify: + { + register XGravityEvent *ev = (XGravityEvent *) re; + ev->window = event->u.gravity.window; + ev->event = event->u.gravity.event; + ev->x = cvtINT16toInt(event->u.gravity.x); + ev->y = cvtINT16toInt(event->u.gravity.y); + } + break; + case ResizeRequest: + { + register XResizeRequestEvent *ev = + (XResizeRequestEvent *) re; + ev->window = event->u.resizeRequest.window; + ev->width = event->u.resizeRequest.width; + ev->height = event->u.resizeRequest.height; + } + break; + case CirculateNotify: + { + register XCirculateEvent *ev = (XCirculateEvent *) re; + ev->window = event->u.circulate.window; + ev->event = event->u.circulate.event; + ev->place = event->u.circulate.place; + } + break; + case CirculateRequest: + { + register XCirculateRequestEvent *ev = + (XCirculateRequestEvent *) re; + ev->window = event->u.circulate.window; + ev->parent = event->u.circulate.event; + ev->place = event->u.circulate.place; + } + break; + case PropertyNotify: + { + register XPropertyEvent *ev = (XPropertyEvent *) re; + ev->window = event->u.property.window; + ev->atom = event->u.property.atom; + ev->time = event->u.property.time; + ev->state = event->u.property.state; + } + break; + case SelectionClear: + { + register XSelectionClearEvent *ev = + (XSelectionClearEvent *) re; + ev->window = event->u.selectionClear.window; + ev->selection = event->u.selectionClear.atom; + ev->time = event->u.selectionClear.time; + } + break; + case SelectionRequest: + { + register XSelectionRequestEvent *ev = + (XSelectionRequestEvent *) re; + ev->owner = event->u.selectionRequest.owner; + ev->requestor = event->u.selectionRequest.requestor; + ev->selection = event->u.selectionRequest.selection; + ev->target = event->u.selectionRequest.target; + ev->property = event->u.selectionRequest.property; + ev->time = event->u.selectionRequest.time; + } + break; + case SelectionNotify: + { + register XSelectionEvent *ev = (XSelectionEvent *) re; + ev->requestor = event->u.selectionNotify.requestor; + ev->selection = event->u.selectionNotify.selection; + ev->target = event->u.selectionNotify.target; + ev->property = event->u.selectionNotify.property; + ev->time = event->u.selectionNotify.time; + } + break; + case ColormapNotify: + { + register XColormapEvent *ev = (XColormapEvent *) re; + ev->window = event->u.colormap.window; + ev->colormap = event->u.colormap.colormap; + ev->new = event->u.colormap.new; + ev->state = event->u.colormap.state; + } + break; + case ClientMessage: + { + register int i; + register XClientMessageEvent *ev + = (XClientMessageEvent *) re; + ev->window = event->u.clientMessage.window; + ev->format = event->u.u.detail; + switch (ev->format) { + case 8: + ev->message_type = event->u.clientMessage.u.b.type; + for (i = 0; i < 20; i++) + ev->data.b[i] = event->u.clientMessage.u.b.bytes[i]; + break; + case 16: + ev->message_type = event->u.clientMessage.u.s.type; + ev->data.s[0] = cvtINT16toShort(event->u.clientMessage.u.s.shorts0); + ev->data.s[1] = cvtINT16toShort(event->u.clientMessage.u.s.shorts1); + ev->data.s[2] = cvtINT16toShort(event->u.clientMessage.u.s.shorts2); + ev->data.s[3] = cvtINT16toShort(event->u.clientMessage.u.s.shorts3); + ev->data.s[4] = cvtINT16toShort(event->u.clientMessage.u.s.shorts4); + ev->data.s[5] = cvtINT16toShort(event->u.clientMessage.u.s.shorts5); + ev->data.s[6] = cvtINT16toShort(event->u.clientMessage.u.s.shorts6); + ev->data.s[7] = cvtINT16toShort(event->u.clientMessage.u.s.shorts7); + ev->data.s[8] = cvtINT16toShort(event->u.clientMessage.u.s.shorts8); + ev->data.s[9] = cvtINT16toShort(event->u.clientMessage.u.s.shorts9); + break; + case 32: + ev->message_type = event->u.clientMessage.u.l.type; + ev->data.l[0] = cvtINT32toLong(event->u.clientMessage.u.l.longs0); + ev->data.l[1] = cvtINT32toLong(event->u.clientMessage.u.l.longs1); + ev->data.l[2] = cvtINT32toLong(event->u.clientMessage.u.l.longs2); + ev->data.l[3] = cvtINT32toLong(event->u.clientMessage.u.l.longs3); + ev->data.l[4] = cvtINT32toLong(event->u.clientMessage.u.l.longs4); + break; + default: /* XXX should never occur */ + break; + } + } + break; + case MappingNotify: + { + register XMappingEvent *ev = (XMappingEvent *)re; + ev->window = 0; + ev->first_keycode = event->u.mappingNotify.firstKeyCode; + ev->request = event->u.mappingNotify.request; + ev->count = event->u.mappingNotify.count; + } + break; + default: + return(_XUnknownWireEvent(dpy, re, event)); + } + return(True); +} + + +#ifndef USL_SHARELIB + +static char *_SysErrorMsg (n) + int n; +{ + char *s = strerror(n); + + return (s ? s : "no such error"); +} + +#endif /* USL sharedlibs in don't define for SVR3.2 */ + + +/* + * _XDefaultIOError - Default fatal system error reporting routine. Called + * when an X internal system error is encountered. + */ +void _XDefaultIOError (dpy) + Display *dpy; +{ + if (ECHECK(EPIPE)) { + (void) fprintf (stderr, + "X connection to %s broken (explicit kill or server shutdown).\r\n", + DisplayString (dpy)); + } else { + (void) fprintf (stderr, + "XIO: fatal IO error %d (%s) on X server \"%s\"\r\n", +#ifdef WIN32 + WSAGetLastError(), strerror(WSAGetLastError()), +#else + errno, _SysErrorMsg (errno), +#endif + DisplayString (dpy)); + (void) fprintf (stderr, + " after %lu requests (%lu known processed) with %d events remaining.\r\n", + NextRequest(dpy) - 1, LastKnownRequestProcessed(dpy), + QLength(dpy)); + + } + exit(1); +} + + +static int _XPrintDefaultError (dpy, event, fp) + Display *dpy; + XErrorEvent *event; + FILE *fp; +{ + char buffer[BUFSIZ]; + char mesg[BUFSIZ]; + char number[32]; + char *mtype = "XlibMessage"; + register _XExtension *ext = (_XExtension *)NULL; + _XExtension *bext = (_XExtension *)NULL; + XGetErrorText(dpy, event->error_code, buffer, BUFSIZ); + XGetErrorDatabaseText(dpy, mtype, "XError", "X Error", mesg, BUFSIZ); + (void) fprintf(fp, "%s: %s\n ", mesg, buffer); + XGetErrorDatabaseText(dpy, mtype, "MajorCode", "Request Major code %d", + mesg, BUFSIZ); + (void) fprintf(fp, mesg, event->request_code); + if (event->request_code < 128) { + sprintf(number, "%d", event->request_code); + XGetErrorDatabaseText(dpy, "XRequest", number, "", buffer, BUFSIZ); + } else { + for (ext = dpy->ext_procs; + ext && (ext->codes.major_opcode != event->request_code); + ext = ext->next) + ; + if (ext) + strcpy(buffer, ext->name); + else + buffer[0] = '\0'; + } + (void) fprintf(fp, " (%s)\n", buffer); + if (event->request_code >= 128) { + XGetErrorDatabaseText(dpy, mtype, "MinorCode", "Request Minor code %d", + mesg, BUFSIZ); + fputs(" ", fp); + (void) fprintf(fp, mesg, event->minor_code); + if (ext) { + sprintf(mesg, "%s.%d", ext->name, event->minor_code); + XGetErrorDatabaseText(dpy, "XRequest", mesg, "", buffer, BUFSIZ); + (void) fprintf(fp, " (%s)", buffer); + } + fputs("\n", fp); + } + if (event->error_code >= 128) { + /* kludge, try to find the extension that caused it */ + buffer[0] = '\0'; + for (ext = dpy->ext_procs; ext; ext = ext->next) { + if (ext->error_string) + (*ext->error_string)(dpy, event->error_code, &ext->codes, + buffer, BUFSIZ); + if (buffer[0]) { + bext = ext; + break; + } + if (ext->codes.first_error && + ext->codes.first_error < (int)event->error_code && + (!bext || ext->codes.first_error > bext->codes.first_error)) + bext = ext; + } + if (bext) + sprintf(buffer, "%s.%d", bext->name, + event->error_code - bext->codes.first_error); + else + strcpy(buffer, "Value"); + XGetErrorDatabaseText(dpy, mtype, buffer, "", mesg, BUFSIZ); + if (mesg[0]) { + fputs(" ", fp); + (void) fprintf(fp, mesg, event->resourceid); + fputs("\n", fp); + } + /* let extensions try to print the values */ + for (ext = dpy->ext_procs; ext; ext = ext->next) { + if (ext->error_values) + (*ext->error_values)(dpy, event, fp); + } + } else if ((event->error_code == BadWindow) || + (event->error_code == BadPixmap) || + (event->error_code == BadCursor) || + (event->error_code == BadFont) || + (event->error_code == BadDrawable) || + (event->error_code == BadColor) || + (event->error_code == BadGC) || + (event->error_code == BadIDChoice) || + (event->error_code == BadValue) || + (event->error_code == BadAtom)) { + if (event->error_code == BadValue) + XGetErrorDatabaseText(dpy, mtype, "Value", "Value 0x%x", + mesg, BUFSIZ); + else if (event->error_code == BadAtom) + XGetErrorDatabaseText(dpy, mtype, "AtomID", "AtomID 0x%x", + mesg, BUFSIZ); + else + XGetErrorDatabaseText(dpy, mtype, "ResourceID", "ResourceID 0x%x", + mesg, BUFSIZ); + fputs(" ", fp); + (void) fprintf(fp, mesg, event->resourceid); + fputs("\n", fp); + } + XGetErrorDatabaseText(dpy, mtype, "ErrorSerial", "Error Serial #%d", + mesg, BUFSIZ); + fputs(" ", fp); + (void) fprintf(fp, mesg, event->serial); + XGetErrorDatabaseText(dpy, mtype, "CurrentSerial", "Current Serial #%d", + mesg, BUFSIZ); + fputs("\n ", fp); + (void) fprintf(fp, mesg, dpy->request); + fputs("\n", fp); + if (event->error_code == BadImplementation) return 0; + return 1; +} + +int _XDefaultError(dpy, event) + Display *dpy; + XErrorEvent *event; +{ + if (_XPrintDefaultError (dpy, event, stderr) == 0) return 0; + exit(1); + /*NOTREACHED*/ +} + +/*ARGSUSED*/ +Bool _XDefaultWireError(display, he, we) + Display *display; + XErrorEvent *he; + xError *we; +{ + return True; +} + +/* + * _XError - upcall internal or user protocol error handler + */ +int _XError (dpy, rep) + Display *dpy; + register xError *rep; +{ + /* + * X_Error packet encountered! We need to unpack the error before + * giving it to the user. + */ + XEvent event; /* make it a large event */ + register _XAsyncHandler *async, *next; + + event.xerror.serial = _XSetLastRequestRead(dpy, (xGenericReply *)rep); + + for (async = dpy->async_handlers; async; async = next) { + next = async->next; + if ((*async->handler)(dpy, (xReply *)rep, + (char *)rep, SIZEOF(xError), async->data)) + return 0; + } + + event.xerror.display = dpy; + event.xerror.type = X_Error; + event.xerror.resourceid = rep->resourceID; + event.xerror.error_code = rep->errorCode; + event.xerror.request_code = rep->majorCode; + event.xerror.minor_code = rep->minorCode; + if (dpy->error_vec && + !(*dpy->error_vec[rep->errorCode])(dpy, &event.xerror, rep)) + return 0; + if (_XErrorFunction != NULL) { + int rtn_val; +#ifdef XTHREADS + if (dpy->lock) + (*dpy->lock->user_lock_display)(dpy); + UnlockDisplay(dpy); +#endif /* XTHREADS */ + rtn_val = (*_XErrorFunction)(dpy, (XErrorEvent *)&event); /* upcall */ +#ifdef XTHREADS + LockDisplay(dpy); + if (dpy->lock) + (*dpy->lock->user_unlock_display)(dpy); +#endif /* XTHREADS */ + return rtn_val; + } else { + return _XDefaultError(dpy, (XErrorEvent *)&event); + } +} + +/* + * _XIOError - call user connection error handler and exit + */ +_XIOError (dpy) + Display *dpy; +{ + dpy->flags |= XlibDisplayIOError; +#ifdef WIN32 + errno = WSAGetLastError(); +#endif + + if (_XIOErrorFunction != NULL) + (*_XIOErrorFunction)(dpy); + else + _XDefaultIOError(dpy); + exit (1); +} + + +/* + * This routine can be used to (cheaply) get some memory within a single + * Xlib routine for scratch space. A single buffer is reused each time + * if possible. To be MT safe, you can only call this between a call to + * GetReq* and a call to Data* or _XSend*, or in a context when the thread + * is guaranteed to not unlock the display. + */ +char *_XAllocScratch (dpy, nbytes) + register Display *dpy; + unsigned long nbytes; +{ + if (nbytes > dpy->scratch_length) { + if (dpy->scratch_buffer) Xfree (dpy->scratch_buffer); + if ((dpy->scratch_buffer = Xmalloc((unsigned) nbytes))) + dpy->scratch_length = nbytes; + else dpy->scratch_length = 0; + } + return (dpy->scratch_buffer); +} + +/* + * Scratch space allocator you can call any time, multiple times, and be + * MT safe, but you must hand the buffer back with _XFreeTemp. + */ +char *_XAllocTemp (dpy, nbytes) + register Display *dpy; + unsigned long nbytes; +{ + char *buf; + + buf = _XAllocScratch(dpy, nbytes); + dpy->scratch_buffer = NULL; + dpy->scratch_length = 0; + return buf; +} + +void _XFreeTemp (dpy, buf, nbytes) + register Display *dpy; + char *buf; + unsigned long nbytes; +{ + if (dpy->scratch_buffer) + Xfree(dpy->scratch_buffer); + dpy->scratch_buffer = buf; + dpy->scratch_length = nbytes; +} + +/* + * Given a visual id, find the visual structure for this id on this display. + */ +Visual *_XVIDtoVisual (dpy, id) + Display *dpy; + VisualID id; +{ + register int i, j, k; + register Screen *sp; + register Depth *dp; + register Visual *vp; + for (i = 0; i < dpy->nscreens; i++) { + sp = &dpy->screens[i]; + for (j = 0; j < sp->ndepths; j++) { + dp = &sp->depths[j]; + /* if nvisuals == 0 then visuals will be NULL */ + for (k = 0; k < dp->nvisuals; k++) { + vp = &dp->visuals[k]; + if (vp->visualid == id) return (vp); + } + } + } + return (NULL); +} + +#if NeedFunctionPrototypes +XFree (void *data) +#else +XFree (data) + char *data; +#endif +{ + Xfree (data); + return 1; +} + +#ifdef _XNEEDBCOPYFUNC +void _Xbcopy(b1, b2, length) + register char *b1, *b2; + register length; +{ + if (b1 < b2) { + b2 += length; + b1 += length; + while (length--) + *--b2 = *--b1; + } else { + while (length--) + *b2++ = *b1++; + } +} +#endif + +#ifdef DataRoutineIsProcedure +void Data (dpy, data, len) + Display *dpy; + char *data; + long len; +{ + if (dpy->bufptr + (len) <= dpy->bufmax) { + memcpy(dpy->bufptr, data, (int)len); + dpy->bufptr += ((len) + 3) & ~3; + } else { + _XSend(dpy, data, len); + } +} +#endif /* DataRoutineIsProcedure */ + + +#ifdef LONG64 +_XData32 (dpy, data, len) + Display *dpy; + register long *data; + unsigned len; +{ + register int *buf; + register long i; + + while (len) { + buf = (int *)dpy->bufptr; + i = dpy->bufmax - (char *)buf; + if (!i) { + _XFlush(dpy); + continue; + } + if (len < i) + i = len; + dpy->bufptr = (char *)buf + i; + len -= i; + i >>= 2; + while (--i >= 0) + *buf++ = *data++; + } +} +#endif /* LONG64 */ + +#ifdef WORD64 + +/* + * XXX This is a *really* stupid way of doing this. It should just use + * dpy->bufptr directly, taking into account where in the word it is. + */ + +/* + * Data16 - Place 16 bit data in the buffer. + * + * "dpy" is a pointer to a Display. + * "data" is a pointer to the data. + * "len" is the length in bytes of the data. + */ + +static doData16(dpy, data, len, packbuffer) + register Display *dpy; + short *data; + unsigned len; + char *packbuffer; +{ + long *lp,*lpack; + long i, nwords,bits; + long mask16 = 0x000000000000ffff; + + lp = (long *)data; + lpack = (long *)packbuffer; + +/* nwords is the number of 16 bit values to be packed, + * the low order 16 bits of each word will be packed + * into 64 bit words + */ + nwords = len >> 1; + bits = 48; + + for(i=0;i<nwords;i++){ + if (bits == 48) *lpack = 0; + *lpack ^= (*lp & mask16) << bits; + bits -= 16 ; + lp++; + if(bits < 0){ + lpack++; + bits = 48; + } + } + Data(dpy, packbuffer, len); +} + +_XData16 (dpy, data, len) + Display *dpy; + short *data; + unsigned len; +{ + char packbuffer[PACKBUFFERSIZE]; + unsigned nunits = PACKBUFFERSIZE >> 1; + + for (; len > PACKBUFFERSIZE; len -= PACKBUFFERSIZE, data += nunits) { + doData16 (dpy, data, PACKBUFFERSIZE, packbuffer); + } + if (len) doData16 (dpy, data, len, packbuffer); +} + +/* + * Data32 - Place 32 bit data in the buffer. + * + * "dpy" is a pointer to a Display. + * "data" is a pointer to the data. + * "len" is the length in bytes of the data. + */ + +static doData32 (dpy, data, len, packbuffer) + register Display *dpy; + long *data; + unsigned len; + char *packbuffer; +{ + long *lp,*lpack; + long i,bits,nwords; + long mask32 = 0x00000000ffffffff; + + lpack = (long *) packbuffer; + lp = data; + +/* nwords is the number of 32 bit values to be packed + * the low order 32 bits of each word will be packed + * into 64 bit words + */ + nwords = len >> 2; + bits = 32; + + for(i=0;i<nwords;i++){ + if (bits == 32) *lpack = 0; + *lpack ^= (*lp & mask32) << bits; + bits = bits ^32; + lp++; + if(bits) + lpack++; + } + Data(dpy, packbuffer, len); +} + +_XData32 (dpy, data, len) + Display *dpy; + long *data; + unsigned len; +{ + char packbuffer[PACKBUFFERSIZE]; + unsigned nunits = PACKBUFFERSIZE >> 2; + + for (; len > PACKBUFFERSIZE; len -= PACKBUFFERSIZE, data += nunits) { + doData32 (dpy, data, PACKBUFFERSIZE, packbuffer); + } + if (len) doData32 (dpy, data, len, packbuffer); +} + +#endif /* WORD64 */ + + +/* Make sure this produces the same string as DefineLocal/DefineSelf in xdm. + * Otherwise, Xau will not be able to find your cookies in the Xauthority file. + * + * Note: POSIX says that the ``nodename'' member of utsname does _not_ have + * to have sufficient information for interfacing to the network, + * and so, you may be better off using gethostname (if it exists). + */ + +#if (defined(_POSIX_SOURCE) && !defined(AIXV3)) || defined(hpux) || defined(USG) || defined(SVR4) +#define NEED_UTSNAME +#include <sys/utsname.h> +#endif + +/* + * _XGetHostname - similar to gethostname but allows special processing. + */ +int _XGetHostname (buf, maxlen) + char *buf; + int maxlen; +{ + int len; + +#ifdef NEED_UTSNAME + struct utsname name; + + if (maxlen <= 0 || buf == NULL) + return 0; + + uname (&name); + len = strlen (name.nodename); + if (len >= maxlen) len = maxlen - 1; + strncpy (buf, name.nodename, len); + buf[len] = '\0'; +#else + if (maxlen <= 0 || buf == NULL) + return 0; + + buf[0] = '\0'; + (void) gethostname (buf, maxlen); + buf [maxlen - 1] = '\0'; + len = strlen(buf); +#endif /* NEED_UTSNAME */ + return len; +} + + +/* + * _XScreenOfWindow - get the Screen of a given window + */ + +Screen *_XScreenOfWindow (dpy, w) + Display *dpy; + Window w; +{ + register int i; + Window root; + int x, y; /* dummy variables */ + unsigned int width, height, bw, depth; /* dummy variables */ + + if (XGetGeometry (dpy, w, &root, &x, &y, &width, &height, + &bw, &depth) == False) { + return None; + } + for (i = 0; i < ScreenCount (dpy); i++) { /* find root from list */ + if (root == RootWindow (dpy, i)) { + return ScreenOfDisplay (dpy, i); + } + } + return NULL; +} + + +#if (MSKCNT > 4) +/* + * This is a macro if MSKCNT <= 4 + */ +_XANYSET(src) + long *src; +{ + int i; + + for (i=0; i<MSKCNT; i++) + if (src[ i ]) + return (1); + return (0); +} +#endif + +#if defined(WIN32) || defined(__EMX__) /* || defined(OS2) */ + +/* + * These functions are intended to be used internally to Xlib only. + * These functions will always prefix the path with a DOS drive in the + * form "<drive-letter>:". As such, these functions are only suitable + * for use by Xlib function that supply a root-based path to some + * particular file, e.g. <ProjectRoot>/lib/X11/locale/locale.dir will + * be converted to "C:/usr/X11R6.3/lib/X11/locale/locale.dir". + */ + +static int access_file (path, pathbuf, len_pathbuf, pathret) + char* path; + char* pathbuf; + int len_pathbuf; + char** pathret; +{ + if (access (path, F_OK) == 0) { + if (strlen (path) < len_pathbuf) + *pathret = pathbuf; + else + *pathret = Xmalloc (strlen (path) + 1); + if (*pathret) { + strcpy (*pathret, path); + return 1; + } + } + return 0; +} + +static int AccessFile (path, pathbuf, len_pathbuf, pathret) + char* path; + char* pathbuf; + int len_pathbuf; + char** pathret; +{ + unsigned long drives; + int i, len; + char* drive; + char buf[MAX_PATH]; + char* bufp; + + /* just try the "raw" name first and see if it works */ + if (access_file (path, pathbuf, len_pathbuf, pathret)) + return 1; + + /* try the places set in the environment */ + drive = getenv ("_XBASEDRIVE"); +#ifdef __EMX__ + if (!drive) + drive = getenv ("X11ROOT"); +#endif + if (!drive) + drive = "C:"; + len = strlen (drive) + strlen (path); + if (len < MAX_PATH) bufp = buf; + else bufp = Xmalloc (len + 1); + strcpy (bufp, drive); + strcat (bufp, path); + if (access_file (bufp, pathbuf, len_pathbuf, pathret)) { + if (bufp != buf) Xfree (bufp); + return 1; + } + +#ifndef __EMX__ + /* one last place to look */ + drive = getenv ("HOMEDRIVE"); + if (drive) { + len = strlen (drive) + strlen (path); + if (len < MAX_PATH) bufp = buf; + else bufp = Xmalloc (len + 1); + strcpy (bufp, drive); + strcat (bufp, path); + if (access_file (bufp, pathbuf, len_pathbuf, pathret)) { + if (bufp != buf) Xfree (bufp); + return 1; + } + } + + /* tried everywhere else, go fishing */ +#define C_DRIVE ('C' - 'A') +#define Z_DRIVE ('Z' - 'A') + /* does OS/2 (with or with gcc-emx) have getdrives? */ + drives = _getdrives (); + for (i = C_DRIVE; i <= Z_DRIVE; i++) { /* don't check on A: or B: */ + if ((1 << i) & drives) { + len = 2 + strlen (path); + if (len < MAX_PATH) bufp = buf; + else bufp = Xmalloc (len + 1); + *bufp = 'A' + i; + *(bufp + 1) = ':'; + *(bufp + 2) = '\0'; + strcat (bufp, path); + if (access_file (bufp, pathbuf, len_pathbuf, pathret)) { + if (bufp != buf) Xfree (bufp); + return 1; + } + } + } +#endif + return 0; +} + +int _XOpenFile(path, flags) + char* path; + int flags; +{ + char buf[MAX_PATH]; + char* bufp; + int ret = -1; + UINT olderror = SetErrorMode (SEM_FAILCRITICALERRORS); + + if (AccessFile (path, buf, MAX_PATH, &bufp)) + ret = open (bufp, flags); + + (void) SetErrorMode (olderror); + + if (bufp != buf) Xfree (bufp); + + return ret; +} + +void* _XFopenFile(path, mode) + char* path; + char* mode; +{ + char buf[MAX_PATH]; + char* bufp; + void* ret = NULL; + UINT olderror = SetErrorMode (SEM_FAILCRITICALERRORS); + + if (AccessFile (path, buf, MAX_PATH, &bufp)) + ret = fopen (bufp, mode); + + (void) SetErrorMode (olderror); + + if (bufp != buf) Xfree (bufp); + + return ret; +} + +int _XAccessFile(path) + char* path; +{ + char buf[MAX_PATH]; + char* bufp; + int ret = -1; + UINT olderror = SetErrorMode (SEM_FAILCRITICALERRORS); + + ret = AccessFile (path, buf, MAX_PATH, &bufp); + + (void) SetErrorMode (olderror); + + if (bufp != buf) Xfree (bufp); + + return ret; +} + +#endif + diff --git a/src/XomGeneric.h b/src/XomGeneric.h new file mode 100644 index 00000000..10dea3b3 --- /dev/null +++ b/src/XomGeneric.h @@ -0,0 +1,181 @@ +/* $Xorg: XomGeneric.h,v 1.3 2000/08/17 19:45:08 cpqbld Exp $ */ +/* + * Copyright 1992, 1993 by TOSHIBA Corp. + * + * 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 TOSHIBA not be used in advertising + * or publicity pertaining to distribution of the software without specific, + * written prior permission. TOSHIBA make no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * TOSHIBA DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING + * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL + * TOSHIBA 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. + * + * Author: Katsuhisa Yano TOSHIBA Corp. + * mopi@osa.ilab.toshiba.co.jp + */ +/* + * Copyright 1995 by FUJITSU LIMITED + * This is source code modified by FUJITSU LIMITED under the Joint + * Development Agreement for the CDE/Motif PST. + * + * Modifier: Takanori Tateno FUJITSU LIMITED + * + */ + +#ifndef _XOMGENERIC_H_ +#define _XOMGENERIC_H_ + +#include "XlcPublic.h" + +#define XOM_GENERIC(om) (&((XOMGeneric) om)->gen) +#define XOC_GENERIC(font_set) (&((XOCGeneric) font_set)->gen) + +/* For VW/UDC */ +typedef struct _CodeRangeRec { + unsigned long start; + unsigned long end; + unsigned long dmy1; + unsigned long dmy2; +} CodeRangeRec, *CodeRange; + +typedef struct _VRotateRec { + char *charset_name; /* Charset name */ + XlcSide side; /* Encoding side */ + int num_cr; + CodeRange code_range; + char *xlfd_name; + XFontStruct *font; +} VRotateRec, *VRotate; + +typedef enum { + XOMMultiByte, + XOMWideChar +} XOMTextType; + +typedef struct _FontDataRec { + char *name; + XlcSide side; + /* For VW/UDC */ + int scopes_num; + FontScope scopes; + char *xlfd_name; + XFontStruct *font; +} FontDataRec, *FontData; + +#define VROTATE_NONE 0 +#define VROTATE_PART 1 +#define VROTATE_ALL 2 + +typedef struct _OMDataRec { + int charset_count; + XlcCharSet *charset_list; + int font_data_count; + FontData font_data; + /* For VW/UDC */ + int substitute_num; + FontData substitute; + /* Vertical Writing */ + int vmap_num; + FontData vmap; + int vrotate_type; + int vrotate_num; + CodeRange vrotate; +} OMDataRec, *OMData; + +typedef struct _XOMGenericPart { + int data_num; + OMData data; + Bool on_demand_loading; + char *object_name; +} XOMGenericPart; + +typedef struct _XOMGenericRec { + XOMMethods methods; + XOMCoreRec core; + XOMGenericPart gen; +} XOMGenericRec, *XOMGeneric; + +/* + * XOC dependent data + */ + +typedef struct _FontSetRec { + int id; + int charset_count; + XlcCharSet *charset_list; + int font_data_count; + FontData font_data; + char *font_name; + XFontStruct *info; + XFontStruct *font; + XlcSide side; + Bool is_xchar2b; + /* For VW/UDC */ + int substitute_num; + FontData substitute; + /* Vertical Writing */ + int vpart_initialize; + int vmap_num; + FontData vmap; + int vrotate_num; + VRotate vrotate; +} FontSetRec, *FontSet; + +typedef struct _XOCGenericPart { + XlcConv mbs_to_cs; + XlcConv wcs_to_cs; + int font_set_num; + FontSet font_set; +} XOCGenericPart; + +typedef struct _XOCGenericRec { + XOCMethods methods; + XOCCoreRec core; + XOCGenericPart gen; +} XOCGenericRec, *XOCGeneric; + +_XFUNCPROTOBEGIN + +extern XOM _XomGenericOpenOM( +#if NeedFunctionPrototypes + XLCd /* lcd */, + Display* /* dpy */, + XrmDatabase /* rdb */, + _Xconst char* /* res_name */, + _Xconst char* /* res_class */ +#endif +); + +extern XlcConv _XomInitConverter( +#if NeedFunctionPrototypes + XOC /* oc */, + XOMTextType /* type */ +#endif +); + +extern int _XomConvert( +#if NeedFunctionPrototypes + XOC /* oc */, + XlcConv /* conv */, + XPointer* /* from */, + int* /* from_left */, + XPointer* /* to */, + int* /* to_left */, + XPointer* /* args */, + int /* num_args */ +#endif +); + +_XFUNCPROTOEND + +#endif /* _XOMGENERIC_H_ */ diff --git a/src/Xrm.c b/src/Xrm.c new file mode 100644 index 00000000..022dbe60 --- /dev/null +++ b/src/Xrm.c @@ -0,0 +1,2667 @@ +/* $Xorg: Xrm.c,v 1.7 2001/02/09 02:03:39 xorgcvs Exp $ */ + +/*********************************************************** +Copyright 1987, 1988, 1990 by Digital Equipment Corporation, Maynard + + 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 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. + +******************************************************************/ +/* + +Copyright 1987, 1988, 1990, 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. + +*/ + +#include <stdio.h> +#include <ctype.h> +#include "Xlibint.h" +#include <X11/Xresource.h> +#include "Xlcint.h" +#ifdef XTHREADS +#include "locking.h" +#endif +#include "XrmI.h" +#include <X11/Xos.h> + +#ifdef __STDC__ +#define Const const +#else +#define Const /**/ +#endif +#if defined(__STDC__) && !defined(NORCONST) +#define RConst const +#else +#define RConst /**/ +#endif + +/* + +These Xrm routines allow very fast lookup of resources in the resource +database. Several usage patterns are exploited: + +(1) Widgets get a lot of resources at one time. Rather than look up each from +scratch, we can precompute the prioritized list of database levels once, then +search for each resource starting at the beginning of the list. + +(2) Many database levels don't contain any leaf resource nodes. There is no +point in looking for resources on a level that doesn't contain any. This +information is kept on a per-level basis. + +(3) Sometimes the widget instance tree is structured such that you get the same +class name repeated on the fully qualified widget name. This can result in the +same database level occuring multiple times on the search list. The code below +only checks to see if you get two identical search lists in a row, rather than +look back through all database levels, but in practice this removes all +duplicates I've ever observed. + +Joel McCormack + +*/ + +/* + +The Xrm representation has been completely redesigned to substantially reduce +memory and hopefully improve performance. + +The database is structured into two kinds of tables: LTables that contain +only values, and NTables that contain only other tables. + +Some invariants: + +The next pointer of the top-level node table points to the top-level leaf +table, if any. + +Within an LTable, for a given name, the tight value always precedes the +loose value, and if both are present the loose value is always right after +the tight value. + +Within an NTable, all of the entries for a given name are contiguous, +in the order tight NTable, loose NTable, tight LTable, loose LTable. + +Bob Scheifler + +*/ + +typedef unsigned long Signature; + +static XrmQuark XrmQString, XrmQANY; + +typedef Bool (*DBEnumProc)( +#if NeedNestedPrototypes /* this is Nested on purpose, to match Xlib.h */ + XrmDatabase* /* db */, + XrmBindingList /* bindings */, + XrmQuarkList /* quarks */, + XrmRepresentation* /* type */, + XrmValue* /* value */, + XPointer /* closure */ +#endif +); + +typedef struct _VEntry { + struct _VEntry *next; /* next in chain */ + XrmQuark name; /* name of this entry */ + unsigned int tight:1; /* 1 if it is a tight binding */ + unsigned int string:1; /* 1 if type is String */ + unsigned int size:30; /* size of value */ +} VEntryRec, *VEntry; + + +typedef struct _DEntry { + VEntryRec entry; /* entry */ + XrmRepresentation type; /* representation type */ +} DEntryRec, *DEntry; + +/* the value is right after the structure */ +#define StringValue(ve) (XPointer)((ve) + 1) +#define RepType(ve) ((DEntry)(ve))->type +/* the value is right after the structure */ +#define DataValue(ve) (XPointer)(((DEntry)(ve)) + 1) +#define RawValue(ve) (char *)((ve)->string ? StringValue(ve) : DataValue(ve)) + +typedef struct _NTable { + struct _NTable *next; /* next in chain */ + XrmQuark name; /* name of this entry */ + unsigned int tight:1; /* 1 if it is a tight binding */ + unsigned int leaf:1; /* 1 if children are values */ + unsigned int hasloose:1; /* 1 if has loose children */ + unsigned int hasany:1; /* 1 if has ANY entry */ + unsigned int pad:4; /* unused */ + unsigned int mask:8; /* hash size - 1 */ + unsigned int entries:16; /* number of children */ +} NTableRec, *NTable; + +/* the buckets are right after the structure */ +#define NodeBuckets(ne) ((NTable *)((ne) + 1)) +#define NodeHash(ne,q) NodeBuckets(ne)[(q) & (ne)->mask] + +/* leaf tables have an extra level of indirection for the buckets, + * so that resizing can be done without invalidating a search list. + * This is completely ugly, and wastes some memory, but the Xlib + * spec doesn't really specify whether invalidation is OK, and the + * old implementation did not invalidate. + */ +typedef struct _LTable { + NTableRec table; + VEntry *buckets; +} LTableRec, *LTable; + +#define LeafHash(le,q) (le)->buckets[(q) & (le)->table.mask] + +/* An XrmDatabase just holds a pointer to the first top-level table. + * The type name is no longer descriptive, but better to not change + * the Xresource.h header file. This type also gets used to define + * XrmSearchList, which is a complete crock, but we'll just leave it + * and caste types as required. + */ +typedef struct _XrmHashBucketRec { + NTable table; + XPointer mbstate; + XrmMethods methods; +#ifdef XTHREADS + LockInfoRec linfo; +#endif +} XrmHashBucketRec; + +/* closure used in get/put resource */ +typedef struct _VClosure { + XrmRepresentation *type; /* type of value */ + XrmValuePtr value; /* value itself */ +} VClosureRec, *VClosure; + +/* closure used in get search list */ +typedef struct _SClosure { + LTable *list; /* search list */ + int idx; /* index of last filled element */ + int limit; /* maximum index */ +} SClosureRec, *SClosure; + +/* placed in XrmSearchList to indicate next table is loose only */ +#define LOOSESEARCH ((LTable)1) + +/* closure used in enumerate database */ +typedef struct _EClosure { + XrmDatabase db; /* the database */ + DBEnumProc proc; /* the user proc */ + XPointer closure; /* the user closure */ + XrmBindingList bindings; /* binding list */ + XrmQuarkList quarks; /* quark list */ + int mode; /* XrmEnum<kind> */ +} EClosureRec, *EClosure; + +/* predicate to determine when to resize a hash table */ +#define GrowthPred(n,m) ((unsigned)(n) > (((m) + 1) << 2)) + +#define GROW(prev) \ + if (GrowthPred((*prev)->entries, (*prev)->mask)) \ + GrowTable(prev) + +/* pick a reasonable value for maximum depth of resource database */ +#define MAXDBDEPTH 100 + +/* macro used in get/search functions */ + +/* find an entry named ename, with leafness given by leaf */ +#define NFIND(ename) \ + q = ename; \ + entry = NodeHash(table, q); \ + while (entry && entry->name != q) \ + entry = entry->next; \ + if (leaf && entry && !entry->leaf) { \ + entry = entry->next; \ + if (entry && !entry->leaf) \ + entry = entry->next; \ + if (entry && entry->name != q) \ + entry = (NTable)NULL; \ + } + +/* resourceQuarks keeps track of what quarks have been associated with values + * in all LTables. If a quark has never been used in an LTable, we don't need + * to bother looking for it. + */ + +static unsigned char *resourceQuarks = (unsigned char *)NULL; +static XrmQuark maxResourceQuark = -1; + +/* determines if a quark has been used for a value in any database */ +#define IsResourceQuark(q) ((q) > 0 && (q) <= maxResourceQuark && \ + resourceQuarks[(q) >> 3] & (1 << ((q) & 7))) + +typedef unsigned char XrmBits; + +#define BSLASH ((XrmBits) (1 << 5)) +#define NORMAL ((XrmBits) (1 << 4)) +#define EOQ ((XrmBits) (1 << 3)) +#define SEP ((XrmBits) (1 << 2)) +#define ENDOF ((XrmBits) (1 << 1)) +#define SPACE (NORMAL|EOQ|SEP|(XrmBits)0) +#define RSEP (NORMAL|EOQ|SEP|(XrmBits)1) +#define EOS (EOQ|SEP|ENDOF|(XrmBits)0) +#define EOL (EOQ|SEP|ENDOF|(XrmBits)1) +#define BINDING (NORMAL|EOQ) +#define ODIGIT (NORMAL|(XrmBits)1) + +#define next_char(ch,str) xrmtypes[(unsigned char)((ch) = *(++(str)))] +#define next_mbchar(ch,len,str) xrmtypes[(unsigned char)(ch = (*db->methods->mbchar)(db->mbstate, str, &len), str += len, ch)] + +#define is_space(bits) ((bits) == SPACE) +#define is_EOQ(bits) ((bits) & EOQ) +#define is_EOF(bits) ((bits) == EOS) +#define is_EOL(bits) ((bits) & ENDOF) +#define is_binding(bits) ((bits) == BINDING) +#define is_odigit(bits) ((bits) == ODIGIT) +#define is_separator(bits) ((bits) & SEP) +#define is_nonpcs(bits) (!(bits)) +#define is_normal(bits) ((bits) & NORMAL) +#define is_simple(bits) ((bits) & (NORMAL|BSLASH)) +#define is_special(bits) ((bits) & (ENDOF|BSLASH)) + +/* parsing types */ +static XrmBits Const xrmtypes[256] = { + EOS,0,0,0,0,0,0,0, + 0,SPACE,EOL,0,0, +#if defined(WIN32) || defined(__EMX__) /* || defined(OS2) */ + EOL, /* treat CR the same as LF, just in case */ +#else + 0, +#endif + 0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + SPACE,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL, + NORMAL,NORMAL,BINDING,NORMAL,NORMAL,NORMAL,BINDING,NORMAL, + ODIGIT,ODIGIT,ODIGIT,ODIGIT,ODIGIT,ODIGIT,ODIGIT,ODIGIT, + NORMAL,NORMAL,RSEP,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL, + NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL, + NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL, + NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL, + NORMAL,NORMAL,NORMAL,NORMAL,BSLASH,NORMAL,NORMAL,NORMAL, + NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL, + NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL, + NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL, + NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,0 + /* The rest will be automatically initialized to zero. */ +}; + +void XrmInitialize() +{ + XrmQString = XrmPermStringToQuark("String"); + XrmQANY = XrmPermStringToQuark("?"); +} + +XrmDatabase XrmGetDatabase(display) + Display *display; +{ + XrmDatabase retval; + LockDisplay(display); + retval = display->db; + UnlockDisplay(display); + return retval; +} + +void XrmSetDatabase(display, database) + Display *display; + XrmDatabase database; +{ + LockDisplay(display); + display->db = database; + UnlockDisplay(display); +} + +#if NeedFunctionPrototypes +void XrmStringToQuarkList( + register _Xconst char *name, + register XrmQuarkList quarks) /* RETURN */ +#else +void XrmStringToQuarkList(name, quarks) + register char *name; + register XrmQuarkList quarks; /* RETURN */ +#endif +{ + register XrmBits bits; + register Signature sig = 0; + register char ch, *tname; + register int i = 0; + + if ((tname = (char *)name)) { + tname--; + while (!is_EOF(bits = next_char(ch, tname))) { + if (is_binding (bits)) { + if (i) { + /* Found a complete name */ + *quarks++ = _XrmInternalStringToQuark(name,tname - name, + sig, False); + i = 0; + sig = 0; + } + name = tname+1; + } + else { + sig = (sig << 1) + ch; /* Compute the signature. */ + i++; + } + } + *quarks++ = _XrmInternalStringToQuark(name, tname - name, sig, False); + } + *quarks = NULLQUARK; +} + +#if NeedFunctionPrototypes +void XrmStringToBindingQuarkList( + register _Xconst char *name, + register XrmBindingList bindings, /* RETURN */ + register XrmQuarkList quarks) /* RETURN */ +#else +void XrmStringToBindingQuarkList(name, bindings, quarks) + register char *name; + register XrmBindingList bindings; /* RETURN */ + register XrmQuarkList quarks; /* RETURN */ +#endif +{ + register XrmBits bits; + register Signature sig = 0; + register char ch, *tname; + register XrmBinding binding; + register int i = 0; + + if ((tname = (char *)name)) { + tname--; + binding = XrmBindTightly; + while (!is_EOF(bits = next_char(ch, tname))) { + if (is_binding (bits)) { + if (i) { + /* Found a complete name */ + *bindings++ = binding; + *quarks++ = _XrmInternalStringToQuark(name, tname - name, + sig, False); + + i = 0; + sig = 0; + binding = XrmBindTightly; + } + name = tname+1; + + if (ch == '*') + binding = XrmBindLoosely; + } + else { + sig = (sig << 1) + ch; /* Compute the signature. */ + i++; + } + } + *bindings = binding; + *quarks++ = _XrmInternalStringToQuark(name, tname - name, sig, False); + } + *quarks = NULLQUARK; +} + +#ifdef DEBUG + +static void PrintQuarkList(quarks, stream) + XrmQuarkList quarks; + FILE *stream; +{ + Bool firstNameSeen; + + for (firstNameSeen = False; *quarks; quarks++) { + if (firstNameSeen) { + (void) fprintf(stream, "."); + } + firstNameSeen = True; + (void) fputs(XrmQuarkToString(*quarks), stream); + } +} /* PrintQuarkList */ + +#endif /* DEBUG */ + +/*ARGSUSED*/ +static void mbnoop(state) + XPointer state; +{ +} + +/*ARGSUSED*/ +static char mbchar(state, str, lenp) + XPointer state; + char *str; + int *lenp; +{ + *lenp = 1; + return *str; +} + +/*ARGSUSED*/ +static char *lcname(state) + XPointer state; +{ + return "C"; +} + +static RConst XrmMethodsRec mb_methods = { + mbnoop, + mbchar, + mbnoop, + lcname, + mbnoop +}; + +static XrmDatabase NewDatabase() +{ + register XrmDatabase db; + + db = (XrmDatabase) Xmalloc(sizeof(XrmHashBucketRec)); + if (db) { + _XCreateMutex(&db->linfo); + db->table = (NTable)NULL; + db->mbstate = (XPointer)NULL; + db->methods = _XrmInitParseInfo(&db->mbstate); + if (!db->methods) + db->methods = (XrmMethods)&mb_methods; + } + return db; +} + +/* move all values from ftable to ttable, and free ftable's buckets. + * ttable is quaranteed empty to start with. + */ +static void MoveValues(ftable, ttable) + LTable ftable; + register LTable ttable; +{ + register VEntry fentry, nfentry; + register VEntry *prev; + register VEntry *bucket; + register VEntry tentry; + register int i; + + for (i = ftable->table.mask, bucket = ftable->buckets; i >= 0; i--) { + for (fentry = *bucket++; fentry; fentry = nfentry) { + prev = &LeafHash(ttable, fentry->name); + tentry = *prev; + *prev = fentry; + /* chain on all with same name, to preserve invariant order */ + while ((nfentry = fentry->next) && nfentry->name == fentry->name) + fentry = nfentry; + fentry->next = tentry; + } + } + Xfree((char *)ftable->buckets); +} + +/* move all tables from ftable to ttable, and free ftable. + * ttable is quaranteed empty to start with. + */ +static void MoveTables(ftable, ttable) + NTable ftable; + register NTable ttable; +{ + register NTable fentry, nfentry; + register NTable *prev; + register NTable *bucket; + register NTable tentry; + register int i; + + for (i = ftable->mask, bucket = NodeBuckets(ftable); i >= 0; i--) { + for (fentry = *bucket++; fentry; fentry = nfentry) { + prev = &NodeHash(ttable, fentry->name); + tentry = *prev; + *prev = fentry; + /* chain on all with same name, to preserve invariant order */ + while ((nfentry = fentry->next) && nfentry->name == fentry->name) + fentry = nfentry; + fentry->next = tentry; + } + } + Xfree((char *)ftable); +} + +/* grow the table, based on current number of entries */ +static void GrowTable(prev) + NTable *prev; +{ + register NTable table; + register int i; + + table = *prev; + i = table->mask; + if (i == 255) /* biggest it gets */ + return; + while (i < 255 && GrowthPred(table->entries, i)) + i = (i << 1) + 1; + i++; /* i is now the new size */ + if (table->leaf) { + register LTable ltable; + LTableRec otable; + + ltable = (LTable)table; + /* cons up a copy to make MoveValues look symmetric */ + otable = *ltable; + ltable->buckets = (VEntry *)Xmalloc(i * sizeof(VEntry)); + if (!ltable->buckets) { + ltable->buckets = otable.buckets; + return; + } + ltable->table.mask = i - 1; + bzero((char *)ltable->buckets, i * sizeof(VEntry)); + MoveValues(&otable, ltable); + } else { + register NTable ntable; + + ntable = (NTable)Xmalloc(sizeof(NTableRec) + i * sizeof(NTable)); + if (!ntable) + return; + *ntable = *table; + ntable->mask = i - 1; + bzero((char *)NodeBuckets(ntable), i * sizeof(NTable)); + *prev = ntable; + MoveTables(table, ntable); + } +} + +/* merge values from ftable into *pprev, destroy ftable in the process */ +static void MergeValues(ftable, pprev, override) + LTable ftable; + NTable *pprev; + Bool override; +{ + register VEntry fentry, tentry; + register VEntry *prev; + register LTable ttable; + VEntry *bucket; + int i; + register XrmQuark q; + + ttable = (LTable)*pprev; + if (ftable->table.hasloose) + ttable->table.hasloose = 1; + for (i = ftable->table.mask, bucket = ftable->buckets; + i >= 0; + i--, bucket++) { + for (fentry = *bucket; fentry; ) { + q = fentry->name; + prev = &LeafHash(ttable, q); + tentry = *prev; + while (tentry && tentry->name != q) + tentry = *(prev = &tentry->next); + /* note: test intentionally uses fentry->name instead of q */ + /* permits serendipitous inserts */ + while (tentry && tentry->name == fentry->name) { + /* if tentry is earlier, skip it */ + if (!fentry->tight && tentry->tight) { + tentry = *(prev = &tentry->next); + continue; + } + if (fentry->tight != tentry->tight) { + /* no match, chain in fentry */ + *prev = fentry; + prev = &fentry->next; + fentry = *prev; + *prev = tentry; + ttable->table.entries++; + } else if (override) { + /* match, chain in fentry, splice out and free tentry */ + *prev = fentry; + prev = &fentry->next; + fentry = *prev; + *prev = tentry->next; + /* free the overridden entry */ + Xfree((char *)tentry); + /* get next tentry */ + tentry = *prev; + } else { + /* match, discard fentry */ + prev = &tentry->next; + tentry = fentry; /* use as a temp var */ + fentry = fentry->next; + /* free the overpowered entry */ + Xfree((char *)tentry); + /* get next tentry */ + tentry = *prev; + } + if (!fentry) + break; + } + /* at this point, tentry cannot match any fentry named q */ + /* chain in all bindings together, preserve invariant order */ + while (fentry && fentry->name == q) { + *prev = fentry; + prev = &fentry->next; + fentry = *prev; + *prev = tentry; + ttable->table.entries++; + } + } + } + Xfree((char *)ftable->buckets); + Xfree((char *)ftable); + /* resize if necessary, now that we're all done */ + GROW(pprev); +} + +/* merge tables from ftable into *pprev, destroy ftable in the process */ +static void MergeTables(ftable, pprev, override) + NTable ftable; + NTable *pprev; + Bool override; +{ + register NTable fentry, tentry; + NTable nfentry; + register NTable *prev; + register NTable ttable; + NTable *bucket; + int i; + register XrmQuark q; + + ttable = *pprev; + if (ftable->hasloose) + ttable->hasloose = 1; + if (ftable->hasany) + ttable->hasany = 1; + for (i = ftable->mask, bucket = NodeBuckets(ftable); + i >= 0; + i--, bucket++) { + for (fentry = *bucket; fentry; ) { + q = fentry->name; + prev = &NodeHash(ttable, q); + tentry = *prev; + while (tentry && tentry->name != q) + tentry = *(prev = &tentry->next); + /* note: test intentionally uses fentry->name instead of q */ + /* permits serendipitous inserts */ + while (tentry && tentry->name == fentry->name) { + /* if tentry is earlier, skip it */ + if ((fentry->leaf && !tentry->leaf) || + (!fentry->tight && tentry->tight && + (fentry->leaf || !tentry->leaf))) { + tentry = *(prev = &tentry->next); + continue; + } + nfentry = fentry->next; + if (fentry->leaf != tentry->leaf || + fentry->tight != tentry->tight) { + /* no match, just chain in */ + *prev = fentry; + *(prev = &fentry->next) = tentry; + ttable->entries++; + } else { + if (fentry->leaf) + MergeValues((LTable)fentry, prev, override); + else + MergeTables(fentry, prev, override); + /* bump to next tentry */ + tentry = *(prev = &(*prev)->next); + } + /* bump to next fentry */ + fentry = nfentry; + if (!fentry) + break; + } + /* at this point, tentry cannot match any fentry named q */ + /* chain in all bindings together, preserve invariant order */ + while (fentry && fentry->name == q) { + *prev = fentry; + prev = &fentry->next; + fentry = *prev; + *prev = tentry; + ttable->entries++; + } + } + } + Xfree((char *)ftable); + /* resize if necessary, now that we're all done */ + GROW(pprev); +} + +void XrmCombineDatabase(from, into, override) + XrmDatabase from, *into; + Bool override; +{ + register NTable *prev; + register NTable ftable, ttable, nftable; + + if (!*into) { + *into = from; + } else if (from) { + _XLockMutex(&from->linfo); + _XLockMutex(&(*into)->linfo); + if ((ftable = from->table)) { + prev = &(*into)->table; + ttable = *prev; + if (!ftable->leaf) { + nftable = ftable->next; + if (ttable && !ttable->leaf) { + /* both have node tables, merge them */ + MergeTables(ftable, prev, override); + /* bump to into's leaf table, if any */ + ttable = *(prev = &(*prev)->next); + } else { + /* into has no node table, link from's in */ + *prev = ftable; + *(prev = &ftable->next) = ttable; + } + /* bump to from's leaf table, if any */ + ftable = nftable; + } else { + /* bump to into's leaf table, if any */ + if (ttable && !ttable->leaf) + ttable = *(prev = &ttable->next); + } + if (ftable) { + /* if into has a leaf, merge, else insert */ + if (ttable) + MergeValues((LTable)ftable, prev, override); + else + *prev = ftable; + } + } + (from->methods->destroy)(from->mbstate); + _XFreeMutex(&from->linfo); + Xfree((char *)from); + _XUnlockMutex(&(*into)->linfo); + } +} + +void XrmMergeDatabases(from, into) + XrmDatabase from, *into; +{ + XrmCombineDatabase(from, into, True); +} + +/* store a value in the database, overriding any existing entry */ +static void PutEntry(db, bindings, quarks, type, value) + XrmDatabase db; + XrmBindingList bindings; + XrmQuarkList quarks; + XrmRepresentation type; + XrmValuePtr value; +{ + register NTable *pprev, *prev; + register NTable table; + register XrmQuark q; + register VEntry *vprev; + register VEntry entry; + NTable *nprev, *firstpprev; + +#define NEWTABLE(q,i) \ + table = (NTable)Xmalloc(sizeof(LTableRec)); \ + if (!table) \ + return; \ + table->name = q; \ + table->hasloose = 0; \ + table->hasany = 0; \ + table->mask = 0; \ + table->entries = 0; \ + if (quarks[i]) { \ + table->leaf = 0; \ + nprev = NodeBuckets(table); \ + } else { \ + table->leaf = 1; \ + if (!(nprev = (NTable *)Xmalloc(sizeof(VEntry *)))) \ + return; \ + ((LTable)table)->buckets = (VEntry *)nprev; \ + } \ + *nprev = (NTable)NULL; \ + table->next = *prev; \ + *prev = table + + if (!db || !*quarks) + return; + table = *(prev = &db->table); + /* if already at leaf, bump to the leaf table */ + if (!quarks[1] && table && !table->leaf) + table = *(prev = &table->next); + pprev = prev; + if (!table || (quarks[1] && table->leaf)) { + /* no top-level node table, create one and chain it in */ + NEWTABLE(NULLQUARK,1); + table->tight = 1; /* arbitrary */ + prev = nprev; + } else { + /* search along until we need a value */ + while (quarks[1]) { + q = *quarks; + table = *(prev = &NodeHash(table, q)); + while (table && table->name != q) + table = *(prev = &table->next); + if (!table) + break; /* not found */ + if (quarks[2]) { + if (table->leaf) + break; /* not found */ + } else { + if (!table->leaf) { + /* bump to leaf table, if any */ + table = *(prev = &table->next); + if (!table || table->name != q) + break; /* not found */ + if (!table->leaf) { + /* bump to leaf table, if any */ + table = *(prev = &table->next); + if (!table || table->name != q) + break; /* not found */ + } + } + } + if (*bindings == XrmBindTightly) { + if (!table->tight) + break; /* not found */ + } else { + if (table->tight) { + /* bump to loose table, if any */ + table = *(prev = &table->next); + if (!table || table->name != q || + !quarks[2] != table->leaf) + break; /* not found */ + } + } + /* found that one, bump to next quark */ + pprev = prev; + quarks++; + bindings++; + } + if (!quarks[1]) { + /* found all the way to a leaf */ + q = *quarks; + entry = *(vprev = &LeafHash((LTable)table, q)); + while (entry && entry->name != q) + entry = *(vprev = &entry->next); + /* if want loose and have tight, bump to next entry */ + if (entry && *bindings == XrmBindLoosely && entry->tight) + entry = *(vprev = &entry->next); + if (entry && entry->name == q && + (*bindings == XrmBindTightly) == entry->tight) { + /* match, need to override */ + if ((type == XrmQString) == entry->string && + entry->size == value->size) { + /* update type if not String, can be different */ + if (!entry->string) + RepType(entry) = type; + /* identical size, just overwrite value */ + memcpy(RawValue(entry), (char *)value->addr, value->size); + return; + } + /* splice out and free old entry */ + *vprev = entry->next; + Xfree((char *)entry); + (*pprev)->entries--; + } + /* this is where to insert */ + prev = (NTable *)vprev; + } + } + /* keep the top table, because we may have to grow it */ + firstpprev = pprev; + /* iterate until we get to the leaf */ + while (quarks[1]) { + /* build a new table and chain it in */ + NEWTABLE(*quarks,2); + if (*quarks++ == XrmQANY) + (*pprev)->hasany = 1; + if (*bindings++ == XrmBindTightly) { + table->tight = 1; + } else { + table->tight = 0; + (*pprev)->hasloose = 1; + } + (*pprev)->entries++; + pprev = prev; + prev = nprev; + } + /* now allocate the value entry */ + entry = (VEntry)Xmalloc(((type == XrmQString) ? + sizeof(VEntryRec) : sizeof(DEntryRec)) + + value->size); + if (!entry) + return; + entry->name = q = *quarks; + if (*bindings == XrmBindTightly) { + entry->tight = 1; + } else { + entry->tight = 0; + (*pprev)->hasloose = 1; + } + /* chain it in, with a bit of type cast ugliness */ + entry->next = *((VEntry *)prev); + *((VEntry *)prev) = entry; + entry->size = value->size; + if (type == XrmQString) { + entry->string = 1; + } else { + entry->string = 0; + RepType(entry) = type; + } + /* save a copy of the value */ + memcpy(RawValue(entry), (char *)value->addr, value->size); + (*pprev)->entries++; + /* this is a new leaf, need to remember it for search lists */ + if (q > maxResourceQuark) { + unsigned oldsize = (maxResourceQuark + 1) >> 3; + unsigned size = ((q | 0x7f) + 1) >> 3; /* reallocate in chunks */ + if (resourceQuarks) { + unsigned char *prevQuarks = resourceQuarks; + + resourceQuarks = (unsigned char *)Xrealloc((char *)resourceQuarks, + size); + if (!resourceQuarks) { + Xfree(prevQuarks); + } + } else + resourceQuarks = (unsigned char *)Xmalloc(size); + if (resourceQuarks) { + bzero((char *)&resourceQuarks[oldsize], size - oldsize); + maxResourceQuark = (size << 3) - 1; + } else { + maxResourceQuark = -1; + } + } + if (q > 0 && resourceQuarks) + resourceQuarks[q >> 3] |= 1 << (q & 0x7); + GROW(firstpprev); + +#undef NEWTABLE +} + +void XrmQPutResource(pdb, bindings, quarks, type, value) + XrmDatabase *pdb; + XrmBindingList bindings; + XrmQuarkList quarks; + XrmRepresentation type; + XrmValuePtr value; +{ + if (!*pdb) *pdb = NewDatabase(); + _XLockMutex(&(*pdb)->linfo); + PutEntry(*pdb, bindings, quarks, type, value); + _XUnlockMutex(&(*pdb)->linfo); +} + +#if NeedFunctionPrototypes +void XrmPutResource( + XrmDatabase *pdb, + _Xconst char *specifier, + _Xconst char *type, + XrmValuePtr value) +#else +void XrmPutResource(pdb, specifier, type, value) + XrmDatabase *pdb; + char *specifier; + char *type; + XrmValuePtr value; +#endif +{ + XrmBinding bindings[MAXDBDEPTH+1]; + XrmQuark quarks[MAXDBDEPTH+1]; + + if (!*pdb) *pdb = NewDatabase(); + _XLockMutex(&(*pdb)->linfo); + XrmStringToBindingQuarkList(specifier, bindings, quarks); + PutEntry(*pdb, bindings, quarks, XrmStringToQuark(type), value); + _XUnlockMutex(&(*pdb)->linfo); +} + +#if NeedFunctionPrototypes +void XrmQPutStringResource( + XrmDatabase *pdb, + XrmBindingList bindings, + XrmQuarkList quarks, + _Xconst char *str) +#else +void XrmQPutStringResource(pdb, bindings, quarks, str) + XrmDatabase *pdb; + XrmBindingList bindings; + XrmQuarkList quarks; + char *str; +#endif +{ + XrmValue value; + + if (!*pdb) *pdb = NewDatabase(); + value.addr = (XPointer) str; + value.size = strlen(str)+1; + _XLockMutex(&(*pdb)->linfo); + PutEntry(*pdb, bindings, quarks, XrmQString, &value); + _XUnlockMutex(&(*pdb)->linfo); +} + +/* Function Name: GetDatabase + * Description: Parses a string and stores it as a database. + * Arguments: db - the database. + * str - a pointer to the string containing the database. + * filename - source filename, if any. + * doall - whether to do all lines or just one + */ + +/* + * This function is highly optimized to inline as much as possible. + * Be very careful with modifications, or simplifications, as they + * may adversely affect the performance. + * + * Chris Peterson, MIT X Consortium 5/17/90. + */ + +/* + * Xlib spec says max 100 quarks in a lookup, will stop and return if + * return if any single production's lhs has more than 100 components. + */ +#define QLIST_SIZE 100 + +/* + * This should be big enough to handle things like the XKeysymDB or biggish + * ~/.Xdefaults or app-defaults files. Anything bigger will be allocated on + * the heap. + */ +#define DEF_BUFF_SIZE 8192 + +static void GetIncludeFile(); + +static void GetDatabase(db, str, filename, doall) + XrmDatabase db; + register char *str; + char *filename; + Bool doall; +{ + char *rhs; + char *lhs, lhs_s[DEF_BUFF_SIZE]; + XrmQuark quarks[QLIST_SIZE + 1]; /* allow for a terminal NullQuark */ + XrmBinding bindings[QLIST_SIZE + 1]; + + register char *ptr; + register XrmBits bits = 0; + register char c; + register Signature sig; + register char *ptr_max; + register int num_quarks; + register XrmBindingList t_bindings; + + int len, alloc_chars; + unsigned long str_len; + XrmValue value; + Bool only_pcs; + Bool dolines; + + if (!db) + return; + + /* + * if strlen (str) < DEF_BUFF_SIZE allocate buffers on the stack for + * speed otherwise malloc the buffer. From a buffer overflow standpoint + * we can be sure that neither: a) a component on the lhs, or b) a + * value on the rhs, will be longer than the overall length of str, + * i.e. strlen(str). + * + * This should give good performance when parsing "*foo: bar" type + * databases as might be passed with -xrm command line options; but + * with larger databases, e.g. .Xdefaults, app-defaults, or KeysymDB + * files, the size of the buffers will be overly large. One way + * around this would be to double-parse each production with a resulting + * performance hit. In any event we can be assured that a lhs component + * name or a rhs value won't be longer than str itself. + */ + + str_len = strlen (str); + if (DEF_BUFF_SIZE > str_len) lhs = lhs_s; + else if ((lhs = (char*) Xmalloc (str_len)) == NULL) + return; + + alloc_chars = DEF_BUFF_SIZE < str_len ? str_len : DEF_BUFF_SIZE; + if ((rhs = (char*) Xmalloc (alloc_chars)) == NULL) { + if (lhs != lhs_s) Xfree (lhs); + return; + } + + (*db->methods->mbinit)(db->mbstate); + str--; + dolines = True; + while (!is_EOF(bits) && dolines) { + dolines = doall; + + /* + * First: Remove extra whitespace. + */ + + do { + bits = next_char(c, str); + } while is_space(bits); + + /* + * Ignore empty lines. + */ + + if (is_EOL(bits)) + continue; /* start a new line. */ + + /* + * Second: check the first character in a line to see if it is + * "!" signifying a comment, or "#" signifying a directive. + */ + + if (c == '!') { /* Comment, spin to next newline */ + while (is_simple(bits = next_char(c, str))) {} + if (is_EOL(bits)) + continue; + while (!is_EOL(bits = next_mbchar(c, len, str))) {} + str--; + continue; /* start a new line. */ + } + + if (c == '#') { /* Directive */ + /* remove extra whitespace */ + only_pcs = True; + while (is_space(bits = next_char(c, str))) {}; + /* only "include" directive is currently defined */ + if (!strncmp(str, "include", 7)) { + str += (7-1); + /* remove extra whitespace */ + while (is_space(bits = next_char(c, str))) {}; + /* must have a starting " */ + if (c == '"') { + char *fname = str+1; + len = 0; + do { + if (only_pcs) { + bits = next_char(c, str); + if (is_nonpcs(bits)) + only_pcs = False; + } + if (!only_pcs) + bits = next_mbchar(c, len, str); + } while (c != '"' && !is_EOL(bits)); + /* must have an ending " */ + if (c == '"') + GetIncludeFile(db, filename, fname, str - len - fname); + } + } + /* spin to next newline */ + if (only_pcs) { + while (is_simple(bits)) + bits = next_char(c, str); + if (is_EOL(bits)) + continue; + } + while (!is_EOL(bits)) + bits = next_mbchar(c, len, str); + str--; + continue; /* start a new line. */ + } + + /* + * Third: loop through the LHS of the resource specification + * storing characters and converting this to a Quark. + */ + + num_quarks = 0; + t_bindings = bindings; + + sig = 0; + ptr = lhs; + *t_bindings = XrmBindTightly; + for(;;) { + if (!is_binding(bits)) { + while (!is_EOQ(bits)) { + *ptr++ = c; + sig = (sig << 1) + c; /* Compute the signature. */ + bits = next_char(c, str); + } + + quarks[num_quarks++] = + _XrmInternalStringToQuark(lhs, ptr - lhs, sig, False); + + if (num_quarks > QLIST_SIZE) { + Xfree(rhs); + if (lhs != lhs_s) Xfree (lhs); + (*db->methods->mbfinish)(db->mbstate); + return; + } + + if (is_separator(bits)) { + if (!is_space(bits)) + break; + + /* Remove white space */ + do { + *ptr++ = c; + sig = (sig << 1) + c; /* Compute the signature. */ + } while (is_space(bits = next_char(c, str))); + + /* + * The spec doesn't permit it, but support spaces + * internal to resource name/class + */ + + if (is_separator(bits)) + break; + num_quarks--; + continue; + } + + if (c == '.') + *(++t_bindings) = XrmBindTightly; + else + *(++t_bindings) = XrmBindLoosely; + + sig = 0; + ptr = lhs; + } + else { + /* + * Magic unspecified feature #254. + * + * If two separators appear with no Text between them then + * ignore them. + * + * If anyone of those separators is a '*' then the binding + * will be loose, otherwise it will be tight. + */ + + if (c == '*') + *t_bindings = XrmBindLoosely; + } + + bits = next_char(c, str); + } + + quarks[num_quarks] = NULLQUARK; + + /* + * Make sure that there is a ':' in this line. + */ + + if (c != ':') { + char oldc; + + /* + * A parsing error has occured, toss everything on the line + * a new_line can still be escaped with a '\'. + */ + + while (is_normal(bits)) + bits = next_char(c, str); + if (is_EOL(bits)) + continue; + bits = next_mbchar(c, len, str); + do { + oldc = c; + bits = next_mbchar(c, len, str); + } while (c && (c != '\n' || oldc == '\\')); + str--; + continue; + } + + /* + * I now have a quark and binding list for the entire left hand + * side. "c" currently points to the ":" separating the left hand + * side for the right hand side. It is time to begin processing + * the right hand side. + */ + + /* + * Fourth: Remove more whitespace + */ + + for(;;) { + if (is_space(bits = next_char(c, str))) + continue; + if (c != '\\') + break; + bits = next_char(c, str); + if (c == '\n') + continue; + str--; + bits = BSLASH; + c = '\\'; + break; + } + + /* + * Fifth: Process the right hand side. + */ + + ptr = rhs; + ptr_max = ptr + alloc_chars - 4; + only_pcs = True; + len = 1; + + for(;;) { + + /* + * Tight loop for the normal case: Non backslash, non-end of value + * character that will fit into the allocated buffer. + */ + + if (only_pcs) { + while (is_normal(bits) && ptr < ptr_max) { + *ptr++ = c; + bits = next_char(c, str); + } + if (is_EOL(bits)) + break; + if (is_nonpcs(bits)) { + only_pcs = False; + bits = next_mbchar(c, len, str); + } + } + while (!is_special(bits) && ptr + len <= ptr_max) { + len = -len; + while (len) + *ptr++ = str[len++]; + if (*str == '\0') { + bits = EOS; + break; + } + bits = next_mbchar(c, len, str); + } + + if (is_EOL(bits)) { + str--; + break; + } + + if (c == '\\') { + /* + * We need to do some magic after a backslash. + */ + Bool read_next = True; + + if (only_pcs) { + bits = next_char(c, str); + if (is_nonpcs(bits)) + only_pcs = False; + } + if (!only_pcs) + bits = next_mbchar(c, len, str); + + if (is_EOL(bits)) { + if (is_EOF(bits)) + continue; + } else if (c == 'n') { + /* + * "\n" means insert a newline. + */ + *ptr++ = '\n'; + } else if (c == '\\') { + /* + * "\\" completes to just one backslash. + */ + *ptr++ = '\\'; + } else { + /* + * pick up to three octal digits after the '\'. + */ + char temp[3]; + int count = 0; + while (is_odigit(bits) && count < 3) { + temp[count++] = c; + if (only_pcs) { + bits = next_char(c, str); + if (is_nonpcs(bits)) + only_pcs = False; + } + if (!only_pcs) + bits = next_mbchar(c, len, str); + } + + /* + * If we found three digits then insert that octal code + * into the value string as a character. + */ + + if (count == 3) { + *ptr++ = (unsigned char) ((temp[0] - '0') * 0100 + + (temp[1] - '0') * 010 + + (temp[2] - '0')); + } + else { + int tcount; + + /* + * Otherwise just insert those characters into the + * string, since no special processing is needed on + * numerics we can skip the special processing. + */ + + for (tcount = 0; tcount < count; tcount++) { + *ptr++ = temp[tcount]; /* print them in + the correct order */ + } + } + read_next = False; + } + if (read_next) { + if (only_pcs) { + bits = next_char(c, str); + if (is_nonpcs(bits)) + only_pcs = False; + } + if (!only_pcs) + bits = next_mbchar(c, len, str); + } + } + + /* + * It is important to make sure that there is room for at least + * four more characters in the buffer, since I can add that + * many characters into the buffer after a backslash has occured. + */ + + if (ptr + len > ptr_max) { + char * temp_str; + + alloc_chars += BUFSIZ/10; + temp_str = Xrealloc(rhs, sizeof(char) * alloc_chars); + + if (!temp_str) { + Xfree(rhs); + if (lhs != lhs_s) Xfree (lhs); + (*db->methods->mbfinish)(db->mbstate); + return; + } + + ptr = temp_str + (ptr - rhs); /* reset pointer. */ + rhs = temp_str; + ptr_max = rhs + alloc_chars - 4; + } + } + + /* + * Lastly: Terminate the value string, and store this entry + * into the database. + */ + + *ptr++ = '\0'; + + /* Store it in database */ + value.size = ptr - rhs; + value.addr = (XPointer) rhs; + + PutEntry(db, bindings, quarks, XrmQString, &value); + } + + if (lhs != lhs_s) Xfree (lhs); + Xfree (rhs); + + (*db->methods->mbfinish)(db->mbstate); +} + +#if NeedFunctionPrototypes +void XrmPutStringResource( + XrmDatabase *pdb, + _Xconst char*specifier, + _Xconst char*str) +#else +void XrmPutStringResource(pdb, specifier, str) + XrmDatabase *pdb; + char *specifier; + char *str; +#endif +{ + XrmValue value; + XrmBinding bindings[MAXDBDEPTH+1]; + XrmQuark quarks[MAXDBDEPTH+1]; + + if (!*pdb) *pdb = NewDatabase(); + XrmStringToBindingQuarkList(specifier, bindings, quarks); + value.addr = (XPointer) str; + value.size = strlen(str)+1; + _XLockMutex(&(*pdb)->linfo); + PutEntry(*pdb, bindings, quarks, XrmQString, &value); + _XUnlockMutex(&(*pdb)->linfo); +} + + +#if NeedFunctionPrototypes +void XrmPutLineResource( + XrmDatabase *pdb, + _Xconst char*line) +#else +void XrmPutLineResource(pdb, line) + XrmDatabase *pdb; + char *line; +#endif +{ + if (!*pdb) *pdb = NewDatabase(); + _XLockMutex(&(*pdb)->linfo); + GetDatabase(*pdb, line, (char *)NULL, False); + _XUnlockMutex(&(*pdb)->linfo); +} + +#if NeedFunctionPrototypes +XrmDatabase XrmGetStringDatabase( + _Xconst char *data) +#else +XrmDatabase XrmGetStringDatabase(data) + char *data; +#endif +{ + XrmDatabase db; + + db = NewDatabase(); + _XLockMutex(&db->linfo); + GetDatabase(db, data, (char *)NULL, True); + _XUnlockMutex(&db->linfo); + return db; +} + +/* Function Name: ReadInFile + * Description: Reads the file into a buffer. + * Arguments: filename - the name of the file. + * Returns: An allocated string containing the contents of the file. + */ + +static char * +ReadInFile(filename) +char * filename; +{ + register int fd, size; + char * filebuf; + + /* + * MS-Windows and OS/2 note: Default open mode includes O_TEXT + */ + if ( (fd = _XOpenFile (filename, O_RDONLY)) == -1 ) + return (char *)NULL; + + /* + * MS-Windows and OS/2 note: depending on how the sources are + * untarred, the newlines in resource files may or may not have + * been * expanded to CRLF. Either way the size returned by fstat + * is sufficient to read the file into because in text-mode any + * CRLFs in a file will be converted to newlines (LF) with the + * result that * the number of bytes actually read with be <= + * to the size returned by fstat. + */ + GetSizeOfFile(fd, size); + + if (!(filebuf = Xmalloc(size + 1))) { /* leave room for '\0' */ + close(fd); + return (char *)NULL; + } + size = read (fd, filebuf, size); + + if (size < 0) { + close (fd); + Xfree(filebuf); + return (char *)NULL; + } + close (fd); + + filebuf[size] = '\0'; /* NULL terminate it. */ + return filebuf; +} + +static void +GetIncludeFile(db, base, fname, fnamelen) + XrmDatabase db; + char *base; + char *fname; + int fnamelen; +{ + int len; + char *str; + char realfname[BUFSIZ]; + + if (fnamelen <= 0 || fnamelen >= BUFSIZ) + return; + if (*fname != '/' && base && (str = strrchr(base, '/'))) { + len = str - base + 1; + if (len + fnamelen >= BUFSIZ) + return; + strncpy(realfname, base, len); + strncpy(realfname + len, fname, fnamelen); + realfname[len + fnamelen] = '\0'; + } else { + strncpy(realfname, fname, fnamelen); + realfname[fnamelen] = '\0'; + } + if (!(str = ReadInFile(realfname))) + return; + GetDatabase(db, str, realfname, True); + Xfree(str); +} + +#if NeedFunctionPrototypes +XrmDatabase XrmGetFileDatabase( + _Xconst char *filename) +#else +XrmDatabase XrmGetFileDatabase(filename) + char *filename; +#endif +{ + XrmDatabase db; + char *str; + + if (!(str = ReadInFile(filename))) + return (XrmDatabase)NULL; + + db = NewDatabase(); + _XLockMutex(&db->linfo); + GetDatabase(db, str, filename, True); + _XUnlockMutex(&db->linfo); + Xfree(str); + return db; +} + +#if NeedFunctionPrototypes +Status XrmCombineFileDatabase( + _Xconst char *filename, + XrmDatabase *target, + Bool override) +#else +Status XrmCombineFileDatabase(filename, target, override) + char *filename; + XrmDatabase *target; + Bool override; +#endif +{ + XrmDatabase db; + char *str; + + if (!(str = ReadInFile(filename))) + return 0; + if (override) { + db = *target; + if (!db) + *target = db = NewDatabase(); + } else + db = NewDatabase(); + _XLockMutex(&db->linfo); + GetDatabase(db, str, filename, True); + _XUnlockMutex(&db->linfo); + Xfree(str); + if (!override) + XrmCombineDatabase(db, target, False); + return 1; +} + +/* call the user proc for every value in the table, arbitrary order. + * stop if user proc returns True. level is current depth in database. + */ +/*ARGSUSED*/ +static Bool EnumLTable(table, names, classes, level, closure) + LTable table; + XrmNameList names; + XrmClassList classes; + register int level; + register EClosure closure; +{ + register VEntry *bucket; + register int i; + register VEntry entry; + XrmValue value; + XrmRepresentation type; + Bool tightOk; + + closure->bindings[level] = (table->table.tight ? + XrmBindTightly : XrmBindLoosely); + closure->quarks[level] = table->table.name; + level++; + tightOk = !*names; + closure->quarks[level + 1] = NULLQUARK; + for (i = table->table.mask, bucket = table->buckets; + i >= 0; + i--, bucket++) { + for (entry = *bucket; entry; entry = entry->next) { + if (entry->tight && !tightOk) + continue; + closure->bindings[level] = (entry->tight ? + XrmBindTightly : XrmBindLoosely); + closure->quarks[level] = entry->name; + value.size = entry->size; + if (entry->string) { + type = XrmQString; + value.addr = StringValue(entry); + } else { + type = RepType(entry); + value.addr = DataValue(entry); + } + if ((*closure->proc)(&closure->db, closure->bindings+1, + closure->quarks+1, &type, &value, + closure->closure)) + return True; + } + } + return False; +} + +static Bool EnumAllNTable(table, level, closure) + NTable table; + register int level; + register EClosure closure; +{ + register NTable *bucket; + register int i; + register NTable entry; + XrmQuark empty = NULLQUARK; + + if (level >= MAXDBDEPTH) + return False; + for (i = table->mask, bucket = NodeBuckets(table); + i >= 0; + i--, bucket++) { + for (entry = *bucket; entry; entry = entry->next) { + if (entry->leaf) { + if (EnumLTable((LTable)entry, &empty, &empty, level, closure)) + return True; + } else { + closure->bindings[level] = (entry->tight ? + XrmBindTightly : XrmBindLoosely); + closure->quarks[level] = entry->name; + if (EnumAllNTable(entry, level+1, closure)) + return True; + } + } + } + return False; +} + +/* recurse on every table in the table, arbitrary order. + * stop if user proc returns True. level is current depth in database. + */ +static Bool EnumNTable(table, names, classes, level, closure) + NTable table; + XrmNameList names; + XrmClassList classes; + register int level; + register EClosure closure; +{ + register NTable entry; + register XrmQuark q; + register unsigned int leaf; + Bool (*get)(); + Bool bilevel; + +/* find entries named ename, leafness leaf, tight or loose, and call get */ +#define ITIGHTLOOSE(ename) \ + NFIND(ename); \ + if (entry) { \ + if (leaf == entry->leaf) { \ + if (!leaf && !entry->tight && entry->next && \ + entry->next->name == q && entry->next->tight && \ + (bilevel || entry->next->hasloose) && \ + EnumLTable((LTable)entry->next, names+1, classes+1, \ + level, closure)) \ + return True; \ + if ((*get)(entry, names+1, classes+1, level, closure)) \ + return True; \ + if (entry->tight && (entry = entry->next) && \ + entry->name == q && leaf == entry->leaf && \ + (*get)(entry, names+1, classes+1, level, closure)) \ + return True; \ + } else if (entry->leaf) { \ + if ((bilevel || entry->hasloose) && \ + EnumLTable((LTable)entry, names+1, classes+1, level, closure))\ + return True; \ + if (entry->tight && (entry = entry->next) && \ + entry->name == q && (bilevel || entry->hasloose) && \ + EnumLTable((LTable)entry, names+1, classes+1, level, closure))\ + return True; \ + } \ + } + +/* find entries named ename, leafness leaf, loose only, and call get */ +#define ILOOSE(ename) \ + NFIND(ename); \ + if (entry && entry->tight && (entry = entry->next) && entry->name != q) \ + entry = (NTable)NULL; \ + if (entry) { \ + if (leaf == entry->leaf) { \ + if ((*get)(entry, names+1, classes+1, level, closure)) \ + return True; \ + } else if (entry->leaf && (bilevel || entry->hasloose)) { \ + if (EnumLTable((LTable)entry, names+1, classes+1, level, closure))\ + return True; \ + } \ + } + + if (level >= MAXDBDEPTH) + return False; + closure->bindings[level] = (table->tight ? + XrmBindTightly : XrmBindLoosely); + closure->quarks[level] = table->name; + level++; + if (!*names) { + if (EnumAllNTable(table, level, closure)) + return True; + } else { + if (names[1] || closure->mode == XrmEnumAllLevels) { + get = EnumNTable; /* recurse */ + leaf = 0; + bilevel = !names[1]; + } else { + get = EnumLTable; /* bottom of recursion */ + leaf = 1; + bilevel = False; + } + if (table->hasloose && closure->mode == XrmEnumAllLevels) { + NTable *bucket; + int i; + XrmQuark empty = NULLQUARK; + + for (i = table->mask, bucket = NodeBuckets(table); + i >= 0; + i--, bucket++) { + q = NULLQUARK; + for (entry = *bucket; entry; entry = entry->next) { + if (!entry->tight && entry->name != q && + entry->name != *names && entry->name != *classes) { + q = entry->name; + if (entry->leaf) { + if (EnumLTable((LTable)entry, &empty, &empty, + level, closure)) + return True; + } else { + if (EnumNTable(entry, &empty, &empty, + level, closure)) + return True; + } + } + } + } + } + + ITIGHTLOOSE(*names); /* do name, tight and loose */ + ITIGHTLOOSE(*classes); /* do class, tight and loose */ + if (table->hasany) { + ITIGHTLOOSE(XrmQANY); /* do ANY, tight and loose */ + } + if (table->hasloose) { + while (1) { + names++; + classes++; + if (!*names) + break; + if (!names[1] && closure->mode != XrmEnumAllLevels) { + get = EnumLTable; /* bottom of recursion */ + leaf = 1; + } + ILOOSE(*names); /* loose names */ + ILOOSE(*classes); /* loose classes */ + if (table->hasany) { + ILOOSE(XrmQANY); /* loose ANY */ + } + } + names--; + classes--; + } + } + /* now look for matching leaf nodes */ + entry = table->next; + if (!entry) + return False; + if (entry->leaf) { + if (entry->tight && !table->tight) + entry = entry->next; + } else { + entry = entry->next; + if (!entry || !entry->tight) + return False; + } + if (!entry || entry->name != table->name) + return False; + /* found one */ + level--; + if ((!*names || entry->hasloose) && + EnumLTable((LTable)entry, names, classes, level, closure)) + return True; + if (entry->tight && entry == table->next && (entry = entry->next) && + entry->name == table->name && (!*names || entry->hasloose)) + return EnumLTable((LTable)entry, names, classes, level, closure); + return False; + +#undef ITIGHTLOOSE +#undef ILOOSE +} + +/* call the proc for every value in the database, arbitrary order. + * stop if the proc returns True. + */ +Bool XrmEnumerateDatabase(db, names, classes, mode, proc, closure) + XrmDatabase db; + XrmNameList names; + XrmClassList classes; + int mode; + DBEnumProc proc; + XPointer closure; +{ + XrmBinding bindings[MAXDBDEPTH+2]; + XrmQuark quarks[MAXDBDEPTH+2]; + register NTable table; + EClosureRec eclosure; + Bool retval = False; + + if (!db) + return False; + _XLockMutex(&db->linfo); + eclosure.db = db; + eclosure.proc = proc; + eclosure.closure = closure; + eclosure.bindings = bindings; + eclosure.quarks = quarks; + eclosure.mode = mode; + table = db->table; + if (table && !table->leaf && !*names && mode == XrmEnumOneLevel) + table = table->next; + if (table) { + if (!table->leaf) + retval = EnumNTable(table, names, classes, 0, &eclosure); + else + retval = EnumLTable((LTable)table, names, classes, 0, &eclosure); + } + _XUnlockMutex(&db->linfo); + return retval; +} + +static void PrintBindingQuarkList(bindings, quarks, stream) + XrmBindingList bindings; + XrmQuarkList quarks; + FILE *stream; +{ + Bool firstNameSeen; + + for (firstNameSeen = False; *quarks; bindings++, quarks++) { + if (*bindings == XrmBindLoosely) { + (void) fprintf(stream, "*"); + } else if (firstNameSeen) { + (void) fprintf(stream, "."); + } + firstNameSeen = True; + (void) fputs(XrmQuarkToString(*quarks), stream); + } +} + +/* output out the entry in correct file syntax */ +/*ARGSUSED*/ +static Bool DumpEntry(db, bindings, quarks, type, value, data) + XrmDatabase *db; + XrmBindingList bindings; + XrmQuarkList quarks; + XrmRepresentation *type; + XrmValuePtr value; + XPointer data; +{ + FILE *stream = (FILE *)data; + register unsigned int i; + register char *s; + register char c; + + if (*type != XrmQString) + (void) putc('!', stream); + PrintBindingQuarkList(bindings, quarks, stream); + s = value->addr; + i = value->size; + if (*type == XrmQString) { + (void) fputs(":\t", stream); + if (i) + i--; + } + else + (void) fprintf(stream, "=%s:\t", XrmRepresentationToString(*type)); + if (i && (*s == ' ' || *s == '\t')) + (void) putc('\\', stream); /* preserve leading whitespace */ + while (i--) { + c = *s++; + if (c == '\n') { + if (i) + (void) fputs("\\n\\\n", stream); + else + (void) fputs("\\n", stream); + } else if (c == '\\') + (void) fputs("\\\\", stream); + else if ((c < ' ' && c != '\t') || + ((unsigned char)c >= 0x7f && (unsigned char)c < 0xa0)) + (void) fprintf(stream, "\\%03o", (unsigned char)c); + else + (void) putc(c, stream); + } + (void) putc('\n', stream); + return ferror(stream) != 0; +} + +#ifdef DEBUG + +void PrintTable(table, file) + NTable table; + FILE *file; +{ + XrmBinding bindings[MAXDBDEPTH+1]; + XrmQuark quarks[MAXDBDEPTH+1]; + EClosureRec closure; + XrmQuark empty = NULLQUARK; + + closure.db = (XrmDatabase)NULL; + closure.proc = DumpEntry; + closure.closure = (XPointer)file; + closure.bindings = bindings; + closure.quarks = quarks; + closure.mode = XrmEnumAllLevels; + if (table->leaf) + EnumLTable((LTable)table, &empty, &empty, 0, &closure); + else + EnumNTable(table, &empty, &empty, 0, &closure); +} + +#endif /* DEBUG */ + +#if NeedFunctionPrototypes +void XrmPutFileDatabase( + XrmDatabase db, + _Xconst char *fileName) +#else +void XrmPutFileDatabase(db, fileName) + XrmDatabase db; + char *fileName; +#endif +{ + FILE *file; + XrmQuark empty = NULLQUARK; + + if (!db) return; + if (!(file = fopen(fileName, "w"))) return; + if (XrmEnumerateDatabase(db, &empty, &empty, XrmEnumAllLevels, + DumpEntry, (XPointer) file)) + unlink((char *)fileName); + fclose(file); +} + +/* macros used in get/search functions */ + +/* find entries named ename, leafness leaf, tight or loose, and call get */ +#define GTIGHTLOOSE(ename,looseleaf) \ + NFIND(ename); \ + if (entry) { \ + if (leaf == entry->leaf) { \ + if (!leaf && !entry->tight && entry->next && \ + entry->next->name == q && entry->next->tight && \ + entry->next->hasloose && \ + looseleaf((LTable)entry->next, names+1, classes+1, closure)) \ + return True; \ + if ((*get)(entry, names+1, classes+1, closure)) \ + return True; \ + if (entry->tight && (entry = entry->next) && \ + entry->name == q && leaf == entry->leaf && \ + (*get)(entry, names+1, classes+1, closure)) \ + return True; \ + } else if (entry->leaf) { \ + if (entry->hasloose && \ + looseleaf((LTable)entry, names+1, classes+1, closure)) \ + return True; \ + if (entry->tight && (entry = entry->next) && \ + entry->name == q && entry->hasloose && \ + looseleaf((LTable)entry, names+1, classes+1, closure)) \ + return True; \ + } \ + } + +/* find entries named ename, leafness leaf, loose only, and call get */ +#define GLOOSE(ename,looseleaf) \ + NFIND(ename); \ + if (entry && entry->tight && (entry = entry->next) && entry->name != q) \ + entry = (NTable)NULL; \ + if (entry) { \ + if (leaf == entry->leaf) { \ + if ((*get)(entry, names+1, classes+1, closure)) \ + return True; \ + } else if (entry->leaf && entry->hasloose) { \ + if (looseleaf((LTable)entry, names+1, classes+1, closure)) \ + return True; \ + } \ + } + +/* add tight/loose entry to the search list, return True if list is full */ +/*ARGSUSED*/ +static Bool AppendLEntry(table, names, classes, closure) + LTable table; + XrmNameList names; + XrmClassList classes; + register SClosure closure; +{ + /* check for duplicate */ + if (closure->idx >= 0 && closure->list[closure->idx] == table) + return False; + if (closure->idx == closure->limit) + return True; + /* append it */ + closure->idx++; + closure->list[closure->idx] = table; + return False; +} + +/* add loose entry to the search list, return True if list is full */ +/*ARGSUSED*/ +static Bool AppendLooseLEntry(table, names, classes, closure) + LTable table; + XrmNameList names; + XrmClassList classes; + register SClosure closure; +{ + /* check for duplicate */ + if (closure->idx >= 0 && closure->list[closure->idx] == table) + return False; + if (closure->idx >= closure->limit - 1) + return True; + /* append it */ + closure->idx++; + closure->list[closure->idx] = LOOSESEARCH; + closure->idx++; + closure->list[closure->idx] = table; + return False; +} + +/* search for a leaf table */ +static Bool SearchNEntry(table, names, classes, closure) + NTable table; + XrmNameList names; + XrmClassList classes; + SClosure closure; +{ + register NTable entry; + register XrmQuark q; + register unsigned int leaf; + Bool (*get)(); + + if (names[1]) { + get = SearchNEntry; /* recurse */ + leaf = 0; + } else { + get = AppendLEntry; /* bottom of recursion */ + leaf = 1; + } + GTIGHTLOOSE(*names, AppendLooseLEntry); /* do name, tight and loose */ + GTIGHTLOOSE(*classes, AppendLooseLEntry); /* do class, tight and loose */ + if (table->hasany) { + GTIGHTLOOSE(XrmQANY, AppendLooseLEntry); /* do ANY, tight and loose */ + } + if (table->hasloose) { + while (1) { + names++; + classes++; + if (!*names) + break; + if (!names[1]) { + get = AppendLEntry; /* bottom of recursion */ + leaf = 1; + } + GLOOSE(*names, AppendLooseLEntry); /* loose names */ + GLOOSE(*classes, AppendLooseLEntry); /* loose classes */ + if (table->hasany) { + GLOOSE(XrmQANY, AppendLooseLEntry); /* loose ANY */ + } + } + } + /* now look for matching leaf nodes */ + entry = table->next; + if (!entry) + return False; + if (entry->leaf) { + if (entry->tight && !table->tight) + entry = entry->next; + } else { + entry = entry->next; + if (!entry || !entry->tight) + return False; + } + if (!entry || entry->name != table->name) + return False; + /* found one */ + if (entry->hasloose && + AppendLooseLEntry((LTable)entry, names, classes, closure)) + return True; + if (entry->tight && entry == table->next && (entry = entry->next) && + entry->name == table->name && entry->hasloose) + return AppendLooseLEntry((LTable)entry, names, classes, closure); + return False; +} + +Bool XrmQGetSearchList(db, names, classes, searchList, listLength) + XrmDatabase db; + XrmNameList names; + XrmClassList classes; + XrmSearchList searchList; /* RETURN */ + int listLength; +{ + register NTable table; + SClosureRec closure; + + if (listLength <= 0) + return False; + closure.list = (LTable *)searchList; + closure.idx = -1; + closure.limit = listLength - 2; + if (db) { + _XLockMutex(&db->linfo); + table = db->table; + if (*names) { + if (table && !table->leaf) { + if (SearchNEntry(table, names, classes, &closure)) { + _XUnlockMutex(&db->linfo); + return False; + } + } else if (table && table->hasloose && + AppendLooseLEntry((LTable)table, names, classes, + &closure)) { + _XUnlockMutex(&db->linfo); + return False; + } + } else { + if (table && !table->leaf) + table = table->next; + if (table && + AppendLEntry((LTable)table, names, classes, &closure)) { + _XUnlockMutex(&db->linfo); + return False; + } + } + _XUnlockMutex(&db->linfo); + } + closure.list[closure.idx + 1] = (LTable)NULL; + return True; +} + +Bool XrmQGetSearchResource(searchList, name, class, pType, pValue) + XrmSearchList searchList; + register XrmName name; + register XrmClass class; + XrmRepresentation *pType; /* RETURN */ + XrmValue *pValue; /* RETURN */ +{ + register LTable *list; + register LTable table; + register VEntry entry; + int flags; + +/* find tight or loose entry */ +#define VTIGHTLOOSE(q) \ + entry = LeafHash(table, q); \ + while (entry && entry->name != q) \ + entry = entry->next; \ + if (entry) \ + break + +/* find loose entry */ +#define VLOOSE(q) \ + entry = LeafHash(table, q); \ + while (entry && entry->name != q) \ + entry = entry->next; \ + if (entry) { \ + if (!entry->tight) \ + break; \ + if ((entry = entry->next) && entry->name == q) \ + break; \ + } + + list = (LTable *)searchList; + /* figure out which combination of name and class we need to search for */ + flags = 0; + if (IsResourceQuark(name)) + flags = 2; + if (IsResourceQuark(class)) + flags |= 1; + if (!flags) { + /* neither name nor class has ever been used to name a resource */ + table = (LTable)NULL; + } else if (flags == 3) { + /* both name and class */ + while ((table = *list++)) { + if (table != LOOSESEARCH) { + VTIGHTLOOSE(name); /* do name, tight and loose */ + VTIGHTLOOSE(class); /* do class, tight and loose */ + } else { + table = *list++; + VLOOSE(name); /* do name, loose only */ + VLOOSE(class); /* do class, loose only */ + } + } + } else { + /* just one of name or class */ + if (flags == 1) + name = class; + while ((table = *list++)) { + if (table != LOOSESEARCH) { + VTIGHTLOOSE(name); /* tight and loose */ + } else { + table = *list++; + VLOOSE(name); /* loose only */ + } + } + } + if (table) { + /* found a match */ + if (entry->string) { + *pType = XrmQString; + pValue->addr = StringValue(entry); + } else { + *pType = RepType(entry); + pValue->addr = DataValue(entry); + } + pValue->size = entry->size; + return True; + } + *pType = NULLQUARK; + pValue->addr = (XPointer)NULL; + pValue->size = 0; + return False; + +#undef VTIGHTLOOSE +#undef VLOOSE +} + +/* look for a tight/loose value */ +static Bool GetVEntry(table, names, classes, closure) + LTable table; + XrmNameList names; + XrmClassList classes; + VClosure closure; +{ + register VEntry entry; + register XrmQuark q; + + /* try name first */ + q = *names; + entry = LeafHash(table, q); + while (entry && entry->name != q) + entry = entry->next; + if (!entry) { + /* not found, try class */ + q = *classes; + entry = LeafHash(table, q); + while (entry && entry->name != q) + entry = entry->next; + if (!entry) + return False; + } + if (entry->string) { + *closure->type = XrmQString; + closure->value->addr = StringValue(entry); + } else { + *closure->type = RepType(entry); + closure->value->addr = DataValue(entry); + } + closure->value->size = entry->size; + return True; +} + +/* look for a loose value */ +static Bool GetLooseVEntry(table, names, classes, closure) + LTable table; + XrmNameList names; + XrmClassList classes; + VClosure closure; +{ + register VEntry entry; + register XrmQuark q; + +#define VLOOSE(ename) \ + q = ename; \ + entry = LeafHash(table, q); \ + while (entry && entry->name != q) \ + entry = entry->next; \ + if (entry && entry->tight && (entry = entry->next) && entry->name != q) \ + entry = (VEntry)NULL; + + /* bump to last component */ + while (names[1]) { + names++; + classes++; + } + VLOOSE(*names); /* do name, loose only */ + if (!entry) { + VLOOSE(*classes); /* do class, loose only */ + if (!entry) + return False; + } + if (entry->string) { + *closure->type = XrmQString; + closure->value->addr = StringValue(entry); + } else { + *closure->type = RepType(entry); + closure->value->addr = DataValue(entry); + } + closure->value->size = entry->size; + return True; + +#undef VLOOSE +} + +/* recursive search for a value */ +static Bool GetNEntry(table, names, classes, closure) + NTable table; + XrmNameList names; + XrmClassList classes; + VClosure closure; +{ + register NTable entry; + register XrmQuark q; + register unsigned int leaf; + Bool (*get)(); + NTable otable; + + if (names[2]) { + get = GetNEntry; /* recurse */ + leaf = 0; + } else { + get = GetVEntry; /* bottom of recursion */ + leaf = 1; + } + GTIGHTLOOSE(*names, GetLooseVEntry); /* do name, tight and loose */ + GTIGHTLOOSE(*classes, GetLooseVEntry); /* do class, tight and loose */ + if (table->hasany) { + GTIGHTLOOSE(XrmQANY, GetLooseVEntry); /* do ANY, tight and loose */ + } + if (table->hasloose) { + while (1) { + names++; + classes++; + if (!names[1]) + break; + if (!names[2]) { + get = GetVEntry; /* bottom of recursion */ + leaf = 1; + } + GLOOSE(*names, GetLooseVEntry); /* do name, loose only */ + GLOOSE(*classes, GetLooseVEntry); /* do class, loose only */ + if (table->hasany) { + GLOOSE(XrmQANY, GetLooseVEntry); /* do ANY, loose only */ + } + } + } + /* look for matching leaf tables */ + otable = table; + table = table->next; + if (!table) + return False; + if (table->leaf) { + if (table->tight && !otable->tight) + table = table->next; + } else { + table = table->next; + if (!table || !table->tight) + return False; + } + if (!table || table->name != otable->name) + return False; + /* found one */ + if (table->hasloose && + GetLooseVEntry((LTable)table, names, classes, closure)) + return True; + if (table->tight && table == otable->next) { + table = table->next; + if (table && table->name == otable->name && table->hasloose) + return GetLooseVEntry((LTable)table, names, classes, closure); + } + return False; +} + +Bool XrmQGetResource(db, names, classes, pType, pValue) + XrmDatabase db; + XrmNameList names; + XrmClassList classes; + XrmRepresentation *pType; /* RETURN */ + XrmValuePtr pValue; /* RETURN */ +{ + register NTable table; + VClosureRec closure; + + if (db && *names) { + _XLockMutex(&db->linfo); + closure.type = pType; + closure.value = pValue; + table = db->table; + if (names[1]) { + if (table && !table->leaf) { + if (GetNEntry(table, names, classes, &closure)) { + _XUnlockMutex(&db->linfo); + return True; + } + } else if (table && table->hasloose && + GetLooseVEntry((LTable)table, names, classes, &closure)) { + _XUnlockMutex (&db->linfo); + return True; + } + } else { + if (table && !table->leaf) + table = table->next; + if (table && GetVEntry((LTable)table, names, classes, &closure)) { + _XUnlockMutex(&db->linfo); + return True; + } + } + _XUnlockMutex(&db->linfo); + } + *pType = NULLQUARK; + pValue->addr = (XPointer)NULL; + pValue->size = 0; + return False; +} + +#if NeedFunctionPrototypes +Bool XrmGetResource(db, name_str, class_str, pType_str, pValue) + XrmDatabase db; + _Xconst char *name_str; + _Xconst char *class_str; + XrmString *pType_str; /* RETURN */ + XrmValuePtr pValue; /* RETURN */ +#else +Bool XrmGetResource(db, name_str, class_str, pType_str, pValue) + XrmDatabase db; + XrmString name_str; + XrmString class_str; + XrmString *pType_str; /* RETURN */ + XrmValuePtr pValue; /* RETURN */ +#endif +{ + XrmName names[MAXDBDEPTH+1]; + XrmClass classes[MAXDBDEPTH+1]; + XrmRepresentation fromType; + Bool result; + + XrmStringToNameList(name_str, names); + XrmStringToClassList(class_str, classes); + result = XrmQGetResource(db, names, classes, &fromType, pValue); + (*pType_str) = XrmQuarkToString(fromType); + return result; +} + +/* destroy all values, plus table itself */ +static void DestroyLTable(table) + LTable table; +{ + register int i; + register VEntry *buckets; + register VEntry entry, next; + + buckets = table->buckets; + for (i = table->table.mask; i >= 0; i--, buckets++) { + for (next = *buckets; (entry = next); ) { + next = entry->next; + Xfree((char *)entry); + } + } + Xfree((char *)table->buckets); + Xfree((char *)table); +} + +/* destroy all contained tables, plus table itself */ +static void DestroyNTable(table) + NTable table; +{ + register int i; + register NTable *buckets; + register NTable entry, next; + + buckets = NodeBuckets(table); + for (i = table->mask; i >= 0; i--, buckets++) { + for (next = *buckets; (entry = next); ) { + next = entry->next; + if (entry->leaf) + DestroyLTable((LTable)entry); + else + DestroyNTable(entry); + } + } + Xfree((char *)table); +} + +char *XrmLocaleOfDatabase(db) + XrmDatabase db; +{ + char* retval; + _XLockMutex(&db->linfo); + retval = (*db->methods->lcname)(db->mbstate); + _XUnlockMutex(&db->linfo); + return retval; +} + +void XrmDestroyDatabase(db) + XrmDatabase db; +{ + register NTable table, next; + + if (db) { + _XLockMutex(&db->linfo); + for (next = db->table; (table = next); ) { + next = table->next; + if (table->leaf) + DestroyLTable((LTable)table); + else + DestroyNTable(table); + } + _XFreeMutex(&db->linfo); + (*db->methods->destroy)(db->mbstate); + Xfree((char *)db); + } +} diff --git a/src/XrmI.h b/src/XrmI.h new file mode 100644 index 00000000..949bcd6f --- /dev/null +++ b/src/XrmI.h @@ -0,0 +1,47 @@ +/* $Xorg: XrmI.h,v 1.4 2001/02/09 02:03:39 xorgcvs Exp $ */ +/* + +Copyright 1990, 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. + +*/ + + +/* + * Macros to abstract out reading the file, and getting its size. + * + * You may need to redefine these for various other operating systems. + */ + +#include <X11/Xos.h> +#include <sys/stat.h> + +#define GetSizeOfFile(fd,size) \ +{ \ + struct stat status_buffer; \ + if ( (fstat((fd), &status_buffer)) == -1 ) \ + size = -1; \ + else \ + size = status_buffer.st_size; \ +} diff --git a/src/evtomask.c b/src/evtomask.c new file mode 100644 index 00000000..80047503 --- /dev/null +++ b/src/evtomask.c @@ -0,0 +1,78 @@ +/* $Xorg: evtomask.c,v 1.4 2001/02/09 02:03:39 xorgcvs Exp $ */ +/* + +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. + +*/ + +#include <X11/X.h> + +#ifdef __STDC__ +#define Const const +#else +#define Const /**/ +#endif + +/* + * This array can be used given an event type to determine the mask bits + * that could have generated it. + */ +long Const _Xevent_to_mask [LASTEvent] = { + 0, /* no event 0 */ + 0, /* no event 1 */ + KeyPressMask, /* KeyPress */ + KeyReleaseMask, /* KeyRelease */ + ButtonPressMask, /* ButtonPress */ + ButtonReleaseMask, /* ButtonRelease */ + PointerMotionMask|PointerMotionHintMask|Button1MotionMask| + Button2MotionMask|Button3MotionMask|Button4MotionMask| + Button5MotionMask|ButtonMotionMask, /* MotionNotify */ + EnterWindowMask, /* EnterNotify */ + LeaveWindowMask, /* LeaveNotify */ + FocusChangeMask, /* FocusIn */ + FocusChangeMask, /* FocusOut */ + KeymapStateMask, /* KeymapNotify */ + ExposureMask, /* Expose */ + ExposureMask, /* GraphicsExpose */ + ExposureMask, /* NoExpose */ + VisibilityChangeMask, /* VisibilityNotify */ + SubstructureNotifyMask, /* CreateNotify */ + StructureNotifyMask|SubstructureNotifyMask, /* DestroyNotify */ + StructureNotifyMask|SubstructureNotifyMask, /* UnmapNotify */ + StructureNotifyMask|SubstructureNotifyMask, /* MapNotify */ + SubstructureRedirectMask, /* MapRequest */ + SubstructureNotifyMask|StructureNotifyMask, /* ReparentNotify */ + StructureNotifyMask|SubstructureNotifyMask, /* ConfigureNotify */ + SubstructureRedirectMask, /* ConfigureRequest */ + SubstructureNotifyMask|StructureNotifyMask, /* GravityNotify */ + ResizeRedirectMask, /* ResizeRequest */ + SubstructureNotifyMask|StructureNotifyMask, /* CirculateNotify */ + SubstructureRedirectMask, /* CirculateRequest */ + PropertyChangeMask, /* PropertyNotify */ + 0, /* SelectionClear */ + 0, /* SelectionRequest */ + 0, /* SelectionNotify */ + ColormapChangeMask, /* ColormapNotify */ + 0, /* ClientMessage */ + 0, /* MappingNotify */ +}; diff --git a/src/globals.c b/src/globals.c new file mode 100644 index 00000000..aadfa878 --- /dev/null +++ b/src/globals.c @@ -0,0 +1,235 @@ +/* $Xorg: globals.c,v 1.4 2001/02/09 02:03:39 xorgcvs Exp $ */ +/* + +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. + +*/ + + +/* + * + * Global data + * + * This file should contain only those objects which must be predefined. + */ +#define NEED_EVENTS +#include <X11/Xlibint.h> + + +/* + * If possible, it is useful to have the global data default to a null value. + * Some shared library implementations are *much* happier if there isn't any + * global initialized data. + */ +#ifdef NULL_NOT_ZERO /* then need to initialize */ +#define SetZero(t,var,z) t var = z +#else +#define SetZero(t,var,z) t var +#endif + +#ifdef USL_SHAREDLIB /* then need extra variables */ +/* + * If we need to define extra variables for each global + */ +#if (defined(__STDC__) && !defined(UNIXCPP)) || defined(ANSICPP) +#define ZEROINIT(t,var,val) SetZero(t,var,val); \ + SetZero (long, _libX_##var##Flag, 0); \ + SetZero (void *, _libX_##var##Ptr, NULL) +#else /* else pcc concatenation */ +#define ZEROINIT(t,var,val) SetZero(t,var,val); \ + SetZero (long, _libX_/**/var/**/Flag, 0); \ + SetZero (void *, _libX_/**/var/**/Ptr, NULL) +#endif /* concat ANSI C vs. pcc */ + +#else /* else not USL_SHAREDLIB */ +/* + * no extra crud + */ +#define ZEROINIT(t,var,val) SetZero (t, var, val) + +#endif /* USL_SHAREDLIB */ + + +/* + * Error handlers; used to be in XlibInt.c + */ +ZEROINIT (XErrorHandler, _XErrorFunction, NULL); +ZEROINIT (XIOErrorHandler, _XIOErrorFunction, NULL); +ZEROINIT (_XQEvent *, _qfree, NULL); + + +/* + * Debugging information and display list; used to be in XOpenDis.c + */ +ZEROINIT (int, _Xdebug, 0); +ZEROINIT (Display *, _XHeadOfDisplayList, NULL); + + + +#if 0 +#ifdef STREAMSCONN + + +/* The following are how the Xstream connections are used: */ +/* 1) Local connections over pseudo-tty ports. */ +/* 2) SVR4 local connections using named streams or SVR3.2 */ +/* local connections using streams. */ +/* 3) SVR4 stream pipe code. This code is proprietary and */ +/* the actual code is not included in the XC distribution. */ +/* 4) remote connections using tcp */ +/* 5) remote connections using StarLan */ + +/* + * descriptor block for streams connections + */ + +#include "Xstreams.h" + +char _XsTypeOfStream[100] = { 0 }; + +extern int write(); +extern int close(); +#ifdef SVR4 +extern int _XsSetupSpStream(); +extern int _XsSetupNamedStream(); +#endif +extern int _XsSetupLocalStream(); +extern int _XsConnectLocalClient(); +extern int _XsCallLocalServer(); +extern int _XsReadLocalStream(); +extern int _XsErrorCall(); +extern int _XsWriteLocalStream(); +extern int _XsCloseLocalStream(); +extern int _XsSetupTliStream(); +extern int _XsConnectTliClient(); +extern int _XsCallTliServer(); +extern int _XsReadTliStream(); +extern int _XsWriteTliStream(); +extern int _XsCloseTliStream(); + + +Xstream _XsStream[] = { + + { + /* local connections using pseudo-ttys */ + + _XsSetupLocalStream, + _XsConnectLocalClient, + _XsCallLocalServer, + _XsReadLocalStream, + _XsErrorCall, + write, + close, + NULL + }, + { +#ifdef SVR4 + /* local connections using named streams */ + + _XsSetupNamedStream, +#else + /* local connections using streams */ + _XsSetupLocalStream, +#endif + _XsConnectLocalClient, + _XsCallLocalServer, + _XsReadLocalStream, + _XsErrorCall, + write, + close, + NULL + }, + /* Enhanced Application Compatibility Support */ + { +#ifdef SVR4 + /* SVR4 stream pipe code */ + _XsSetupSpStream, +#else + _XsSetupLocalStream, +#endif + _XsConnectLocalClient, + _XsCallLocalServer, + _XsReadLocalStream, + _XsErrorCall, + write, + close, + NULL + }, + /* End Enhanced Application Compatibility Support */ + + { + /* remote connections using tcp */ + _XsSetupTliStream, + _XsConnectTliClient, + _XsCallTliServer, + _XsReadLocalStream, + _XsErrorCall, + write, + close, + NULL + }, + { + /* remote connections using StarLan */ + _XsSetupTliStream, + _XsConnectTliClient, + _XsCallTliServer, + _XsReadLocalStream, + _XsErrorCall, + write, + close, + NULL + } +}; + + +#endif /* STREAMSCONN */ +#endif + + +#ifdef XTEST1 +/* + * Stuff for input synthesis extension: + */ +/* + * Holds the two event type codes for this extension. The event type codes + * for this extension may vary depending on how many extensions are installed + * already, so the initial values given below will be added to the base event + * code that is aquired when this extension is installed. + * + * These two variables must be available to programs that use this extension. + */ +int XTestInputActionType = 0; +int XTestFakeAckType = 1; +#endif + +/* + * NOTE: any additional external definition NEED + * to be inserted BELOW this point!!! + */ + +/* + * NOTE: any additional external definition NEED + * to be inserted ABOVE this point!!! + */ diff --git a/src/imConv.c b/src/imConv.c new file mode 100644 index 00000000..e16fb4d2 --- /dev/null +++ b/src/imConv.c @@ -0,0 +1,897 @@ +/* $Xorg: imConv.c,v 1.5 2000/08/17 19:45:11 cpqbld Exp $ */ +/****************************************************************** + + Copyright 1991, 1992 by Fuji Xerox Co.,Ltd. + Copyright 1993, 1994 by FUJITSU LIMITED + +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 Fuji Xerox Co.,Ltd. +, and that the name of FUJITSU LIMITED not be used in advertising or +publicity pertaining to distribution of the software without specific, + written prior permission. +Fuji Xerox Co.,Ltd. , and FUJITSU LIMITED makes no representations about +the suitability of this software for any purpose. +It is provided "as is" without express or implied warranty. + +FUJI XEROX CO.,LTD. AND FUJITSU LIMITED DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL FUJI XEROX CO.,LTD. +AND FUJITSU LIMITED 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. + + Auther: Kazunori Nishihara, Fuji Xerox Co.,Ltd. + kaz@ssdev.ksp.fujixerox.co.jp + Modifier: Takashi Fujiwara FUJITSU LIMITED + fujiwara@a80.tech.yk.fujitsu.co.jp + +******************************************************************/ + +#define NEED_EVENTS +#include <stdio.h> +#include "Xlibint.h" +#include "Xlcint.h" +#include "Ximint.h" +#include "XlcPubI.h" +#define XK_PUBLISHING +#include "X11/keysym.h" + +#ifdef XKB +/* + * rather than just call _XLookupString (i.e. the pre-XKB XLookupString) + * do this because with XKB the event may have some funky modifiers that + * _XLookupString doesn't grok. + */ +#include "XKBlib.h" +#define XLOOKUPSTRING lookup_string +#else +#define XLOOKUPSTRING XLookupString +#endif + +/* bit (1<<i) means character is in codeset i */ +unsigned int _Xlatin1[128] = { +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x990ee, 0x88000, 0x89000, 0x89084, 0x0902e, 0x89000, 0x09080, 0x9908e, +0x0908e, 0x89080, 0x88000, 0x89080, 0x89080, 0x990ee, 0x89000, 0x89008, +0x9908e, 0x89080, 0x89084, 0x89084, 0x0908e, 0x89004, 0x89000, 0x99084, +0x0900c, 0x89000, 0x88000, 0x89080, 0x09000, 0x09084, 0x09000, 0x88000, +0x88004, 0x9800e, 0x9800e, 0x98008, 0x9800e, 0x98008, 0x98008, 0x88006, +0x88004, 0x9800e, 0x88004, 0x9800e, 0x88004, 0x9800e, 0x9800e, 0x98004, +0x90000, 0x88004, 0x88004, 0x98006, 0x9800e, 0x98008, 0x9800e, 0x8800e, +0x98008, 0x88004, 0x9800e, 0x9800c, 0x9800e, 0x90002, 0x90000, 0x9800e, +0x88004, 0x9800e, 0x9800e, 0x98008, 0x9800e, 0x98008, 0x98008, 0x88004, +0x88004, 0x9800e, 0x88004, 0x9800e, 0x88004, 0x9800e, 0x9800e, 0x98004, +0x90000, 0x88004, 0x88004, 0x98006, 0x9800e, 0x98008, 0x9800e, 0x8800e, +0x98008, 0x88004, 0x9800e, 0x9800c, 0x9800e, 0x90002, 0x90000, 0x88000 +}; + +/* bit (1<<i) means character is in codeset i */ +unsigned int _Xlatin2[128] = { +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x1800c, 0x10008, 0x00004, 0x00000, 0x0800c, 0x00000, 0x00000, 0x1800c, +0x0800c, 0x00008, 0x00004, 0x00000, 0x00000, 0x1800c, 0x00008, 0x00004, +0x1800c, 0x10008, 0x00008, 0x00000, 0x0800c, 0x00000, 0x00000, 0x00008, +0x0800c, 0x00008, 0x00004, 0x00000, 0x00000, 0x00000, 0x00008, 0x00004, +0x00000, 0x1800c, 0x1800c, 0x00000, 0x1800c, 0x00000, 0x00000, 0x08004, +0x10008, 0x1800c, 0x10008, 0x1800c, 0x00000, 0x18008, 0x18008, 0x00000, +0x00008, 0x00000, 0x00000, 0x18004, 0x1800c, 0x00000, 0x1800c, 0x0800c, +0x00000, 0x00000, 0x0800c, 0x00000, 0x0800c, 0x10000, 0x00000, 0x1800c, +0x00000, 0x1800c, 0x1800c, 0x00000, 0x1800c, 0x00000, 0x00000, 0x08004, +0x10008, 0x1800c, 0x10008, 0x1800c, 0x00000, 0x1800c, 0x1800c, 0x00000, +0x00008, 0x00000, 0x00000, 0x18004, 0x1800c, 0x00000, 0x1800c, 0x0800c, +0x00000, 0x00000, 0x0800c, 0x00000, 0x0800c, 0x10000, 0x00000, 0x0000c +}; + +/* maps Cyrillic keysyms to 8859-5 */ +unsigned char _Xcyrillic[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80 - */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90 - */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xf2, 0xf3, 0xf1, 0xf4, 0xf5, 0xf6, 0xf7, /* 0xa0 - */ + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0x00, 0xfe, 0xff, + 0xf0, 0xa2, 0xa3, 0xa1, 0xa4, 0xa5, 0xa6, 0xa7, /* 0xb0 - */ + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0x00, 0xae, 0xaf, + 0xee, 0xd0, 0xd1, 0xe6, 0xd4, 0xd5, 0xe4, 0xd3, /* 0xc0 - */ + 0xe5, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, + 0xdf, 0xef, 0xe0, 0xe1, 0xe2, 0xe3, 0xd6, 0xd2, /* 0xd0 - */ + 0xec, 0xeb, 0xd7, 0xe8, 0xed, 0xe9, 0xe7, 0xea, + 0xce, 0xb0, 0xb1, 0xc6, 0xb4, 0xb5, 0xc4, 0xb3, /* 0xe0 - */ + 0xc5, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, + 0xbf, 0xcf, 0xc0, 0xc1, 0xc2, 0xc3, 0xb6, 0xb2, /* 0xf0 - */ + 0xcc, 0xcb, 0xb7, 0xc8, 0xcd, 0xc9, 0xc7, 0xca +}; + +/* maps Cyrillic keysyms to KOI8-R */ +unsigned char _Xkoi8[] = + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xa3, 0x00, 0x00, 0x00, 0x00, /* 10 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xb3, 0x00, 0x00, 0x00, 0x00, /* 11 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 12 */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 13 */ + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 14 */ + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 15 */ + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff}; + +unsigned short _Xkoi8_size = sizeof _Xkoi8; + +/* maps Greek keysyms to 8859-7 */ +unsigned char _Xgreek[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80 - */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90 - */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xb6, 0xb8, 0xb9, 0xba, 0xda, 0x00, 0xbc, /* 0xa0 - */ + 0xbe, 0xdb, 0x00, 0xbf, 0x00, 0x00, 0xb5, 0xaf, + 0x00, 0xdc, 0xdd, 0xde, 0xdf, 0xfa, 0xc0, 0xfc, /* 0xb0 - */ + 0xfd, 0xfb, 0xe0, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0xc0 - */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, + 0xd0, 0xd1, 0xd3, 0x00, 0xd4, 0xd5, 0xd6, 0xd7, /* 0xd0 - */ + 0xd8, 0xd9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0xe0 - */ + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, + 0xf0, 0xf1, 0xf3, 0xf2, 0xf4, 0xf5, 0xf6, 0xf7, /* 0xf0 - */ + 0xf8, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + + +static unsigned short keysym_to_unicode_1a1_1ff[] = { + 0x0104, 0x02d8, 0x0141, 0x0000, 0x013d, 0x015a, 0x0000, /* 0x01a0-0x01a7 */ + 0x0000, 0x0160, 0x015e, 0x0164, 0x0179, 0x0000, 0x017d, 0x017b, /* 0x01a8-0x01af */ + 0x0000, 0x0105, 0x02db, 0x0142, 0x0000, 0x013e, 0x015b, 0x02c7, /* 0x01b0-0x01b7 */ + 0x0000, 0x0161, 0x015f, 0x0165, 0x017a, 0x02dd, 0x017e, 0x017c, /* 0x01b8-0x01bf */ + 0x0154, 0x0000, 0x0000, 0x0102, 0x0000, 0x0139, 0x0106, 0x0000, /* 0x01c0-0x01c7 */ + 0x010c, 0x0000, 0x0118, 0x0000, 0x011a, 0x0000, 0x0000, 0x010e, /* 0x01c8-0x01cf */ + 0x0110, 0x0143, 0x0147, 0x0000, 0x0000, 0x0150, 0x0000, 0x0000, /* 0x01d0-0x01d7 */ + 0x0158, 0x016e, 0x0000, 0x0170, 0x0000, 0x0000, 0x0162, 0x0000, /* 0x01d8-0x01df */ + 0x0155, 0x0000, 0x0000, 0x0103, 0x0000, 0x013a, 0x0107, 0x0000, /* 0x01e0-0x01e7 */ + 0x010d, 0x0000, 0x0119, 0x0000, 0x011b, 0x0000, 0x0000, 0x010f, /* 0x01e8-0x01ef */ + 0x0111, 0x0144, 0x0148, 0x0000, 0x0000, 0x0151, 0x0000, 0x0000, /* 0x01f0-0x01f7 */ + 0x0159, 0x016f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0163, 0x02d9 /* 0x01f8-0x01ff */ +}; + +static unsigned short keysym_to_unicode_2a1_2fe[] = { + 0x0126, 0x0000, 0x0000, 0x0000, 0x0000, 0x0124, 0x0000, /* 0x02a0-0x02a7 */ + 0x0000, 0x0130, 0x0000, 0x011e, 0x0134, 0x0000, 0x0000, 0x0000, /* 0x02a8-0x02af */ + 0x0000, 0x0127, 0x0000, 0x0000, 0x0000, 0x0000, 0x0125, 0x0000, /* 0x02b0-0x02b7 */ + 0x0000, 0x0131, 0x0000, 0x011f, 0x0135, 0x0000, 0x0000, 0x0000, /* 0x02b8-0x02bf */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x010a, 0x0108, 0x0000, /* 0x02c0-0x02c7 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x02c8-0x02cf */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0120, 0x0000, 0x0000, /* 0x02d0-0x02d7 */ + 0x011c, 0x0000, 0x0000, 0x0000, 0x0000, 0x016c, 0x015c, 0x0000, /* 0x02d8-0x02df */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x010b, 0x0109, 0x0000, /* 0x02e0-0x02e7 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x02e8-0x02ef */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0121, 0x0000, 0x0000, /* 0x02f0-0x02f7 */ + 0x011d, 0x0000, 0x0000, 0x0000, 0x0000, 0x016c, 0x015d /* 0x02f8-0x02ff */ +}; + +static unsigned short keysym_to_unicode_3a2_3fe[] = { + 0x0138, 0x0156, 0x0000, 0x0128, 0x013b, 0x0000, /* 0x03a0-0x03a7 */ + 0x0000, 0x0000, 0x0112, 0x0122, 0x0166, 0x0000, 0x0000, 0x0000, /* 0x03a8-0x03af */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x013c, 0x0000, /* 0x03b0-0x03b7 */ + 0x0000, 0x0000, 0x0113, 0x0123, 0x0167, 0x014a, 0x0000, 0x014b, /* 0x03b8-0x03bf */ + 0x0100, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x012e, /* 0x03c0-0x03c7 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0116, 0x0000, 0x0000, 0x012a, /* 0x03c8-0x03cf */ + 0x0000, 0x0145, 0x014c, 0x0136, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x03d0-0x03d7 */ + 0x0000, 0x0172, 0x0000, 0x0000, 0x0000, 0x0168, 0x016a, 0x0000, /* 0x03d8-0x03df */ + 0x0101, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x012f, /* 0x03e0-0x03e7 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0117, 0x0000, 0x0000, 0x012b, /* 0x03e8-0x03ef */ + 0x0000, 0x0146, 0x014d, 0x0137, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x03f0-0x03f7 */ + 0x0000, 0x0173, 0x0000, 0x0000, 0x0000, 0x0169, 0x016b /* 0x03f8-0x03ff */ +}; + +static unsigned short keysym_to_unicode_4a1_4df[] = { + 0x3002, 0x3008, 0x3009, 0x3001, 0x30fb, 0x30f2, 0x30a1, /* 0x04a0-0x04a7 */ + 0x30a3, 0x03a5, 0x30a7, 0x30a9, 0x30e3, 0x30e5, 0x30e7, 0x30c3, /* 0x04a8-0x04af */ + 0x30fc, 0x03a2, 0x30a4, 0x30a6, 0x30a8, 0x30aa, 0x30ab, 0x30ad, /* 0x04b0-0x04b7 */ + 0x30af, 0x30b1, 0x30b3, 0x30b5, 0x30b7, 0x30b9, 0x30bb, 0x30bd, /* 0x04b8-0x04bf */ + 0x30bf, 0x30c1, 0x30c4, 0x30c6, 0x30c8, 0x30ca, 0x30cb, 0x30cc, /* 0x04c0-0x04c7 */ + 0x30cd, 0x30ce, 0x30cf, 0x30d2, 0x30d5, 0x30d8, 0x30db, 0x30de, /* 0x04c8-0x04cf */ + 0x30df, 0x30e0, 0x30e1, 0x30e2, 0x30e4, 0x30e6, 0x30e8, 0x30e9, /* 0x04d0-0x04d7 */ + 0x30ea, 0x30eb, 0x30ec, 0x30ed, 0x30ef, 0x30f3, 0x309b, 0x309c /* 0x04d8-0x04df */ +}; + +static unsigned short keysym_to_unicode_5ac_5f2[] = { + 0x060c, 0x0000, 0x0000, 0x0000, /* 0x05ac-0x05af */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x05b0-0x05b7 */ + 0x0000, 0x0000, 0x0000, 0x061b, 0x0000, 0x0000, 0x0000, 0x061f, /* 0x05b8-0x05bf */ + 0x0000, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627, /* 0x05c0-0x05c7 */ + 0x0628, 0x0629, 0x062a, 0x062b, 0x062c, 0x062d, 0x062e, 0x062f, /* 0x05c8-0x05cf */ + 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x0637, /* 0x05d0-0x05d7 */ + 0x0638, 0x0639, 0x063a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x05d8-0x05df */ + 0x0640, 0x0641, 0x0642, 0x0643, 0x0644, 0x0645, 0x0646, 0x0647, /* 0x05e0-0x05e7 */ + 0x0648, 0x0649, 0x064a, 0x064b, 0x064c, 0x064d, 0x064e, 0x064f, /* 0x05e8-0x05ef */ + 0x0650, 0x0651, 0x0652 /* 0x05f0-0x05f7 */ +}; + +static unsigned short keysym_to_unicode_6a1_6ff[] = { + 0x0452, 0x0453, 0x0451, 0x0454, 0x0455, 0x0456, 0x0457, /* 0x06a0-0x06a7 */ + 0x0458, 0x0459, 0x045a, 0x045b, 0x045c, 0x0000, 0x045e, 0x045f, /* 0x06a8-0x06af */ + 0x2116, 0x0402, 0x0403, 0x0401, 0x0404, 0x0405, 0x0406, 0x0407, /* 0x06b0-0x06b7 */ + 0x0408, 0x0409, 0x040a, 0x040b, 0x040c, 0x0000, 0x040e, 0x040f, /* 0x06b8-0x06bf */ + 0x044e, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433, /* 0x06c0-0x06c7 */ + 0x0445, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, /* 0x06c8-0x06cf */ + 0x043f, 0x044f, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432, /* 0x06d0-0x06d7 */ + 0x044c, 0x044b, 0x0437, 0x0448, 0x044d, 0x0449, 0x0447, 0x044a, /* 0x06d8-0x06df */ + 0x042e, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413, /* 0x06e0-0x06e7 */ + 0x0425, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, /* 0x06e8-0x06ef */ + 0x041f, 0x042f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412, /* 0x06f0-0x06f7 */ + 0x042c, 0x042d, 0x0417, 0x0428, 0x042d, 0x0429, 0x0427, 0x042a /* 0x06f8-0x06ff */ +}; + +static unsigned short keysym_to_unicode_7a1_7f9[] = { + 0x0386, 0x0388, 0x0389, 0x038a, 0x03aa, 0x0000, 0x038c, /* 0x07a0-0x07a7 */ + 0x038e, 0x03ab, 0x0000, 0x038f, 0x0000, 0x0000, 0x0385, 0x2015, /* 0x07a8-0x07af */ + 0x0000, 0x03ac, 0x03ad, 0x03ae, 0x03af, 0x03ca, 0x0390, 0x03cc, /* 0x07b0-0x07b7 */ + 0x03cd, 0x03cb, 0x03b0, 0x03ce, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x07b8-0x07bf */ + 0x0000, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, /* 0x07c0-0x07c7 */ + 0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 0x039e, 0x039f, /* 0x07c8-0x07cf */ + 0x03a0, 0x03a1, 0x03a2, 0x03a3, 0x03a4, 0x03a5, 0x03a6, 0x03a7, /* 0x07d0-0x07d7 */ + 0x03a8, 0x03a9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x07d8-0x07df */ + 0x0000, 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7, /* 0x07e0-0x07e7 */ + 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf, /* 0x07e8-0x07ef */ + 0x03c0, 0x03c1, 0x03c2, 0x03c3, 0x03c4, 0x03c5, 0x03c6, 0x03c7, /* 0x07f0-0x07f7 */ + 0x03c8, 0x03c9 /* 0x07f8-0x07ff */ +}; + +static unsigned short keysym_to_unicode_8a4_8fe[] = { + 0x2320, 0x2321, 0x0000, 0x231c, /* 0x08a0-0x08a7 */ + 0x231d, 0x231e, 0x231f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x08a8-0x08af */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x08b0-0x08b7 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x2264, 0x2260, 0x2265, 0x222b, /* 0x08b8-0x08bf */ + 0x2234, 0x0000, 0x221e, 0x0000, 0x0000, 0x2207, 0x0000, 0x0000, /* 0x08c0-0x08c7 */ + 0x2245, 0x2246, 0x0000, 0x0000, 0x0000, 0x0000, 0x22a2, 0x0000, /* 0x08c8-0x08cf */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x221a, 0x0000, /* 0x08d0-0x08d7 */ + 0x0000, 0x0000, 0x2282, 0x2283, 0x2229, 0x222a, 0x2227, 0x2228, /* 0x08d8-0x08df */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x08e0-0x08e7 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x08e8-0x08ef */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0192, 0x0000, /* 0x08f0-0x08f7 */ + 0x0000, 0x0000, 0x0000, 0x2190, 0x2191, 0x2192, 0x2193 /* 0x08f8-0x08ff */ +}; + +static unsigned short keysym_to_unicode_9df_9f8[] = { + 0x2422, /* 0x09d8-0x09df */ + 0x2666, 0x25a6, 0x2409, 0x240c, 0x240d, 0x240a, 0x0000, 0x0000, /* 0x09e0-0x09e7 */ + 0x240a, 0x240b, 0x2518, 0x2510, 0x250c, 0x2514, 0x253c, 0x2500, /* 0x09e8-0x09ef */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x251c, 0x2524, 0x2534, 0x252c, /* 0x09f0-0x09f7 */ + 0x2502 /* 0x09f8-0x09ff */ +}; + +static unsigned short keysym_to_unicode_aa1_afe[] = { + 0x2003, 0x2002, 0x2004, 0x2005, 0x2007, 0x2008, 0x2009, /* 0x0aa0-0x0aa7 */ + 0x200a, 0x2014, 0x2013, 0x0000, 0x0000, 0x0000, 0x2026, 0x2025, /* 0x0aa8-0x0aaf */ + 0x2153, 0x2154, 0x2155, 0x2156, 0x2157, 0x2158, 0x2159, 0x215a, /* 0x0ab0-0x0ab7 */ + 0x2105, 0x0000, 0x0000, 0x2012, 0x2039, 0x2024, 0x203a, 0x0000, /* 0x0ab8-0x0abf */ + 0x0000, 0x0000, 0x0000, 0x215b, 0x215c, 0x215d, 0x215e, 0x0000, /* 0x0ac0-0x0ac7 */ + 0x0000, 0x2122, 0x2120, 0x00ae, 0x25c1, 0x25b7, 0x25cb, 0x25ad, /* 0x0ac8-0x0acf */ + 0x2018, 0x2019, 0x201c, 0x201d, 0x211e, 0x0000, 0x2032, 0x2033, /* 0x0ad0-0x0ad7 */ + 0x0000, 0x271d, 0x0000, 0x220e, 0x25c2, 0x2023, 0x25cf, 0x25ac, /* 0x0ad8-0x0adf */ + 0x25e6, 0x25ab, 0x25ae, 0x25b5, 0x25bf, 0x2606, 0x2022, 0x25aa, /* 0x0ae0-0x0ae7 */ + 0x25b4, 0x25be, 0x261a, 0x261b, 0x2663, 0x2666, 0x2665, 0x0000, /* 0x0ae8-0x0aef */ + 0x2720, 0x2020, 0x2021, 0x2713, 0x2612, 0x266f, 0x266d, 0x2642, /* 0x0af0-0x0af7 */ + 0x2640, 0x2121, 0x2315, 0x2117, 0x2038, 0x201a, 0x201e /* 0x0af8-0x0aff */ +}; + +/* none of the APL keysyms match the Unicode characters */ + +static unsigned short keysym_to_unicode_cdf_cfa[] = { + 0x2017, /* 0x0cd8-0x0cdf */ + 0x05d0, 0x05d1, 0x05d2, 0x05d3, 0x05d4, 0x05d5, 0x05d6, 0x05d7, /* 0x0ce0-0x0ce7 */ + 0x05d8, 0x05d9, 0x05da, 0x05db, 0x05dc, 0x05dd, 0x05de, 0x05df, /* 0x0ce8-0x0cef */ + 0x05e0, 0x05e1, 0x05e2, 0x05e3, 0x05e4, 0x05e5, 0x05e6, 0x05e7, /* 0x0cf0-0x0cf7 */ + 0x05e8, 0x05e9, 0x05ea /* 0x0cf8-0x0cff */ +}; + +static unsigned short keysym_to_unicode_da1_df9[] = { + 0x0e01, 0x0e02, 0x0e03, 0x0e04, 0x0e05, 0x0e06, 0x0e07, /* 0x0da0-0x0da7 */ + 0x0e08, 0x0e09, 0x0e0a, 0x0e0b, 0x0e0c, 0x0e0d, 0x0e0e, 0x0e0f, /* 0x0da8-0x0daf */ + 0x0e10, 0x0e11, 0x0e12, 0x0e13, 0x0e14, 0x0e15, 0x0e16, 0x0e17, /* 0x0db0-0x0db7 */ + 0x0e18, 0x0e19, 0x0e1a, 0x0e1b, 0x0e1c, 0x0e1d, 0x0e1e, 0x0e1f, /* 0x0db8-0x0dbf */ + 0x0e20, 0x0e21, 0x0e22, 0x0e23, 0x0e24, 0x0e25, 0x0e26, 0x0e27, /* 0x0dc0-0x0dc7 */ + 0x0e28, 0x0e29, 0x0e2a, 0x0e2b, 0x0e2c, 0x0e2d, 0x0e2e, 0x0e2f, /* 0x0dc8-0x0dcf */ + 0x0e30, 0x0e31, 0x0e32, 0x0e33, 0x0e34, 0x0e35, 0x0e36, 0x0e37, /* 0x0dd0-0x0dd7 */ + 0x0e38, 0x0e39, 0x0e3a, 0x0e3b, 0x0e3c, 0x0e3d, 0x0e3e, 0x0e3f, /* 0x0dd8-0x0ddf */ + 0x0e40, 0x0e41, 0x0e42, 0x0e43, 0x0e44, 0x0e45, 0x0e46, 0x0e47, /* 0x0de0-0x0de7 */ + 0x0e48, 0x0e49, 0x0e4a, 0x0e4b, 0x0e4c, 0x0e4d, 0x0000, 0x0000, /* 0x0de8-0x0def */ + 0x0e50, 0x0e51, 0x0e52, 0x0e53, 0x0e54, 0x0e55, 0x0e56, 0x0e57, /* 0x0df0-0x0df7 */ + 0x0e58, 0x0e59 /* 0x0df8-0x0dff */ +}; + +static unsigned short keysym_to_unicode_ea0_eff[] = { + 0x0000, 0x1101, 0x1101, 0x11aa, 0x1102, 0x11ac, 0x11ad, 0x1103, /* 0x0ea0-0x0ea7 */ + 0x1104, 0x1105, 0x11b0, 0x11b1, 0x11b2, 0x11b3, 0x11b4, 0x11b5, /* 0x0ea8-0x0eaf */ + 0x11b6, 0x1106, 0x1107, 0x1108, 0x11b9, 0x1109, 0x110a, 0x110b, /* 0x0eb0-0x0eb7 */ + 0x110c, 0x110d, 0x110e, 0x110f, 0x1110, 0x1111, 0x1112, 0x1161, /* 0x0eb8-0x0ebf */ + 0x1162, 0x1163, 0x1164, 0x1165, 0x1166, 0x1167, 0x1168, 0x1169, /* 0x0ec0-0x0ec7 */ + 0x116a, 0x116b, 0x116c, 0x116d, 0x116e, 0x116f, 0x1170, 0x1171, /* 0x0ec8-0x0ecf */ + 0x1172, 0x1173, 0x1174, 0x1175, 0x11a8, 0x11a9, 0x11aa, 0x11ab, /* 0x0ed0-0x0ed7 */ + 0x11ac, 0x11ad, 0x11ae, 0x11af, 0x11b0, 0x11b1, 0x11b2, 0x11b3, /* 0x0ed8-0x0edf */ + 0x11b4, 0x11b5, 0x11b6, 0x11b7, 0x11b8, 0x11b9, 0x11ba, 0x11bb, /* 0x0ee0-0x0ee7 */ + 0x11bc, 0x11bd, 0x11be, 0x11bf, 0x11c0, 0x11c1, 0x11c2, 0x0000, /* 0x0ee8-0x0eef */ + 0x0000, 0x0000, 0x1140, 0x0000, 0x0000, 0x1159, 0x119e, 0x0000, /* 0x0ef0-0x0ef7 */ + 0x11eb, 0x0000, 0x11f9, 0x0000, 0x0000, 0x0000, 0x0000, 0x20a9, /* 0x0ef8-0x0eff */ +}; + +static unsigned short keysym_to_unicode_13bc_13be[] = { + 0x0152, 0x0153, 0x0178 /* 0x13b8-0x13bf */ +}; + +static unsigned short keysym_to_unicode_20a0_20ac[] = { + 0x20a0, 0x20a1, 0x20a2, 0x20a3, 0x20a4, 0x20a5, 0x20a6, 0x20a7, /* 0x20a0-0x20a7 */ + 0x20a8, 0x20a9, 0x20aa, 0x20ab, 0x20ac /* 0x20a8-0x20af */ +}; + +static int keysym_to_ucs4(keysym) + KeySym keysym; +{ + if (keysym > 0 && keysym < 0x100) + return keysym; + else if (keysym > 0x1a0 && keysym < 0x200) + return keysym_to_unicode_1a1_1ff[keysym - 0x1a1]; + else if (keysym > 0x2a0 && keysym < 0x2ff) + return keysym_to_unicode_2a1_2fe[keysym - 0x2a1]; + else if (keysym > 0x3a1 && keysym < 0x3ff) + return keysym_to_unicode_3a2_3fe[keysym - 0x3a2]; + else if (keysym > 0x4a0 && keysym < 0x4e0) + return keysym_to_unicode_4a1_4df[keysym - 0x4a1]; + else if (keysym > 0x5ab && keysym < 0x5f3) + return keysym_to_unicode_5ac_5f2[keysym - 0x5ac]; + else if (keysym > 0x6a0 && keysym < 0x700) + return keysym_to_unicode_6a1_6ff[keysym - 0x6a1]; + else if (keysym > 0x7a0 && keysym < 0x7fa) + return keysym_to_unicode_7a1_7f9[keysym - 0x7a1]; + else if (keysym > 0x8a3 && keysym < 0x8ff) + return keysym_to_unicode_8a4_8fe[keysym - 0x8a4]; + else if (keysym > 0x9de && keysym < 0x9f9) + return keysym_to_unicode_9df_9f8[keysym - 0x9df]; + else if (keysym > 0xaa0 && keysym < 0xaff) + return keysym_to_unicode_aa1_afe[keysym - 0xaa1]; + else if (keysym > 0xcde && keysym < 0xcfb) + return keysym_to_unicode_cdf_cfa[keysym - 0xcdf]; + else if (keysym > 0xda0 && keysym < 0xdfa) + return keysym_to_unicode_da1_df9[keysym - 0xda1]; + else if (keysym > 0xe9f && keysym < 0xf00) + return keysym_to_unicode_ea0_eff[keysym - 0xea0]; + else if (keysym > 0x13bb && keysym < 0x13bf) + return keysym_to_unicode_13bc_13be[keysym - 0x13bc]; + else if (keysym > 0x209f && keysym < 0x20ad) + return keysym_to_unicode_20a0_20ac[keysym - 0x20a0]; + else + return 0; +} + +struct CodesetRec { + unsigned long locale_code; + char* locale_name; + char* escape_seq; +}; + +#define sLatin1 0L +#define sLatin2 1L +#define sLatin3 2L +#define sLatin4 3L +#define sKana 4L +#define sX0201 0x01000004L +#define sArabic 5L +#define sCyrillic 6L +#define sKoi8 0x01000006L +#define sGreek 7L +#define sHebrew 12L +#define sThai 13L +#define sKorean 14L +#define sLatin5 15L +#define sLatin6 16L +#define sLatin7 17L +#define sLatin8 18L +#define sLatin9 19L +#define sCurrency 32L +#define sUTF8 0x02000000L + +static struct CodesetRec CodesetTable[] = { + {sLatin1, "ISO8859-1", "\033-A"}, + {sLatin2, "ISO8859-2", "\033-B"}, + {sLatin3, "ISO8859-3", "\033-C"}, + {sLatin4, "ISO8859-4", "\033-D"}, + {sArabic, "ISO8859-6", "\033-G"}, + {sCyrillic, "ISO8859-5", "\033-L"}, + {sGreek, "ISO8859-7", "\033-F"}, + {sHebrew, "ISO8859-8", "\033-H"}, + {sLatin5, "ISO8859-9", "\033-M"}, + {sLatin6, "ISO8859-10", "\033-V"}, + {sThai, "TACTIS", "\033-T"}, + {sKorean, "ko.euc", "\033$(C"}, + {sThai, "ISO8859-11", "\033-T"}, +#if 0 + {sLatin8, "ISO8859-12", "\033-?"},/* Celtic, superceded by -14 */ + {sLatin7, "ISO8859-13", "\033-?"},/* Baltic Rim */ + {sLatin8 "ISO8859-14", "\033-?"},/* Celtic */ +#endif + {sUTF8, "utf8", "\033%B"}, + /* Non-standard */ + {sKoi8, "KOI8-R", "\033%/1\200\210koi8-r\002"}, + {sLatin9, "FCD8859-15", "\033%/1\200\213fcd8859-15\002"},/* a.k.a. Latin-0 */ +}; + +#define NUM_CODESETS sizeof CodesetTable / sizeof CodesetTable[0] + +#ifndef XK_emdash +#define XK_emdash 0xaa9 +#endif + + +/* ================================================================ */ +/* +File: ConvertUTF.C +Author: Mark E. Davis +Copyright (C) 1994 Taligent, Inc. All rights reserved. + +This code is copyrighted. Under the copyright laws, this code may not +be copied, in whole or part, without prior written consent of Taligent. + +Taligent grants the right to use or reprint this code as long as this +ENTIRE copyright notice is reproduced in the code or reproduction. +The code is provided AS-IS, AND TALIGENT DISCLAIMS ALL WARRANTIES, +EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN +NO EVENT WILL TALIGENT BE LIABLE FOR ANY DAMAGES WHATSOEVER (INCLUDING, +WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS +INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY +LOSS) ARISING OUT OF THE USE OR INABILITY TO USE THIS CODE, EVEN +IF TALIGENT HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +BECAUSE SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF +LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES, THE ABOVE +LIMITATION MAY NOT APPLY TO YOU. + +RESTRICTED RIGHTS LEGEND: Use, duplication, or disclosure by the +government is subject to restrictions as set forth in subparagraph +(c)(l)(ii) of the Rights in Technical Data and Computer Software +clause at DFARS 252.227-7013 and FAR 52.227-19. + +This code may be protected by one or more U.S. and International +Patents. + +TRADEMARKS: Taligent and the Taligent Design Mark are registered +trademarks of Taligent, Inc. +*/ +/* ================================================================ */ + +#define kReplacementCharacter 0x0000FFFDUL +#define kMaximumUCS2 0x0000FFFFUL +#define kMaximumUCS4 0x7FFFFFFFUL + +typedef enum { + ok, /* conversion successful */ + sourceExhausted, /* partial character in source, but hit end */ + targetExhausted /* insuff. room in target for conversion */ +} ConversionResult; + +#define halfShift 10 +#define halfBase 0x0010000UL +#define halfMask 0x3FFUL +#define kSurrogateHighStart 0xD800UL +#define kSurrogateHighEnd 0xDBFFUL +#define kSurrogateLowStart 0xDC00UL +#define kSurrogateLowEnd 0xDFFFUL + +typedef unsigned int UCS4; /* wchar_t, but on AIX, SunOS wchar_t is 16 bits */ +typedef unsigned char UTF8; + +static UCS4 offsetsFromUTF8[6] = { + 0x00000000UL, 0x00003080UL, 0x000E2080UL, + 0x03C82080UL, 0xFA082080UL, 0x82082080UL +}; + +static char bytesFromUTF8[256] = { + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5 +}; + +static UTF8 firstByteMark[7] = { + 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC +}; + +static ConversionResult ConvertUCS4toUTF8 ( + UCS4** sourceStart, UCS4* sourceEnd, + UTF8** targetStart, UTF8* targetEnd) +{ + ConversionResult result = ok; + register UCS4* source = *sourceStart; + register UTF8* target = *targetStart; + while (source < sourceEnd) { + register UCS4 ch; + register unsigned short bytesToWrite = 0; + register const UCS4 byteMask = 0xBF; + register const UCS4 byteMark = 0x80; + ch = *source++; + if (ch >= kSurrogateHighStart && ch <= kSurrogateHighEnd + && source < sourceEnd) { + register UCS4 ch2 = *source; + if (ch2 >= kSurrogateLowStart && ch2 <= kSurrogateLowEnd) { + ch = ((ch - kSurrogateHighStart) << halfShift) + + (ch2 - kSurrogateLowStart) + halfBase; + ++source; + }; + }; + if (ch < 0x80) { bytesToWrite = 1; + } else if (ch < 0x800) { bytesToWrite = 2; + } else if (ch < 0x10000) { bytesToWrite = 3; + } else if (ch < 0x200000) { bytesToWrite = 4; + } else if (ch < 0x4000000) { bytesToWrite = 5; + } else if (ch <= kMaximumUCS4){ bytesToWrite = 6; + } else { bytesToWrite = 2; + ch = kReplacementCharacter; + }; /* I wish there were a smart way to avoid this conditional */ + + target += bytesToWrite; + if (target > targetEnd) { + target -= bytesToWrite; result = targetExhausted; break; + }; + switch (bytesToWrite) { /* note: code falls through cases! */ + case 6: *--target = (ch | byteMark) & byteMask; ch >>= 6; + case 5: *--target = (ch | byteMark) & byteMask; ch >>= 6; + case 4: *--target = (ch | byteMark) & byteMask; ch >>= 6; + case 3: *--target = (ch | byteMark) & byteMask; ch >>= 6; + case 2: *--target = (ch | byteMark) & byteMask; ch >>= 6; + case 1: *--target = ch | firstByteMark[bytesToWrite]; + }; + target += bytesToWrite; + }; + *sourceStart = source; + *targetStart = target; + return result; +} + +/*ARGSUSED*/ +int +#if NeedFunctionPrototypes +_XGetCharCode ( + unsigned long locale_code, + KeySym keysym, + unsigned char* buf, + int nbytes) +#else +_XGetCharCode (locale_code, keysym, buf, nbytes) + unsigned long locale_code; + KeySym keysym; + unsigned char *buf; + int nbytes; +#endif +{ + unsigned long kset; + int count,isLatin1; + + if (locale_code == sUTF8) { + unsigned int ucs4[2]; + unsigned int* ucs4vec[1]; + unsigned char* utf8vec[1]; + + ucs4[0] = keysym_to_ucs4 (keysym); + ucs4[1] = 0; + ucs4vec[0] = ucs4; + utf8vec[0] = buf; + + (void) ConvertUCS4toUTF8 (ucs4vec, &ucs4[1], utf8vec, &buf[nbytes]); + return (strlen ((char*) buf)); + } + + kset = locale_code&0xffffff; + + isLatin1 = ((keysym&0xffffff00)==0); + count = 0; + + if ( keysym == NoSymbol ) + return 0; + else if ((keysym >> 8) == kset) { + count = 1; + switch (kset) { + case sKana: + *buf = (unsigned char)(keysym & 0xff); + if (buf[0] == 0x7e) + count = 0; + break; + case sCyrillic: + if (locale_code == sKoi8) + *buf = _Xkoi8[keysym & 0x7f]; + else + *buf = _Xcyrillic[keysym & 0x7f]; + break; + case sGreek: + *buf = _Xgreek[keysym & 0x7f]; + if (!buf[0]) + count = 0; + break; + default: + *buf = (unsigned char)(keysym & 0xff); + break; + } + } else if ((locale_code != 0) && (isLatin1) && (keysym & 0x80)) { + if (_Xlatin1[keysym & 0x7f] & (1 << kset)) { + /* Most non-latin1 locales use some latin-1 upper half + keysyms as defined by bitpatterns in array latin1. + Enforce it. */ + *buf = (unsigned char)(keysym & 0xff); + count = 1; + } else { + count= 1; + if ((locale_code == sHebrew) && (keysym == XK_multiply)) + *buf = (unsigned char)0xaa; + else if ((locale_code == sHebrew) && (keysym == XK_division)) + *buf = (unsigned char)0xba; + else if ((locale_code == sCyrillic) && (keysym == XK_section)) + *buf = (unsigned char)0xfd; + else if ((locale_code == sX0201) && (keysym == XK_yen)) + *buf = (unsigned char)0x5c; + else count = 0; + } + } else if (isLatin1) { + if ((locale_code == sX0201) && + ((keysym == XK_backslash) || (keysym == XK_asciitilde))) + count = 0; + if ( (keysym&0x80)==0 ) { + *buf = (unsigned char)(keysym&0x7f); + count = 1; + } + } else if ((keysym >> 8) == sLatin2) { + count = 1; + if ((keysym & 0x80) && (_Xlatin2[keysym & 0x7f] & (1 << kset))) + *buf = (unsigned char)(keysym & 0xff); + else if (locale_code == sLatin5) { + if (keysym == XK_Scedilla) + *buf = (unsigned char)0xde; + else if (keysym == XK_scedilla) + *buf = (unsigned char)0xfe; + else count = 0; + } else if (locale_code == sLatin9) { + if (keysym == XK_Scaron) + *buf = (unsigned char)0xa6; + else if (keysym == XK_scaron) + *buf = (unsigned char)0xa8; + else if (keysym == XK_Zcaron) + *buf = (unsigned char)0xb4; + else if (keysym == XK_zcaron) + *buf = (unsigned char)0xb8; + else count = 0; + } else count = 0; + } else if ((keysym >> 8) == sLatin3) { + if (locale_code == sLatin5) { + count = 1; + switch (keysym) { + case XK_Gbreve: *buf = (unsigned char)0xd0; break; + case XK_gbreve: *buf = (unsigned char)0xf0; break; + case XK_Scedilla: *buf = (unsigned char)0xde; break; + case XK_scedilla: *buf = (unsigned char)0xfe; break; + case XK_Iabovedot: *buf = (unsigned char)0xdd; break; + case XK_idotless: *buf = (unsigned char)0xfd; break; + default: count = 0; + } + } + } else if ((keysym >> 8) == sLatin4) { + if (locale_code == sLatin6) { + count = 1; + switch (keysym) { + case XK_Emacron: *buf = (unsigned char)0xa2; break; + case XK_Gcedilla: *buf = (unsigned char)0xa3; break; + case XK_Imacron: *buf = (unsigned char)0xa4; break; + case XK_Lcedilla: *buf = (unsigned char) 0xa8; break; + case XK_Dstroke: *buf = (unsigned char)0xa9; break; + case XK_Scaron: *buf = (unsigned char)0xaa; break; + case XK_Tslash: *buf = (unsigned char)0xab; break; + case XK_Zcaron: *buf = (unsigned char)0xac; break; + case XK_Umacron: *buf = (unsigned char)0xae; break; + case XK_Utilde: *buf = (unsigned char)0xd7; break; + case XK_ENG: *buf = (unsigned char)0xaf; break; + case XK_emacron: *buf = (unsigned char)0xb2; break; + case XK_gcedilla: *buf = (unsigned char)0xb3; break; + case XK_imacron: *buf = (unsigned char)0xb4; break; + case XK_lcedilla: *buf = (unsigned char) 0xb8; break; + case XK_dstroke: *buf = (unsigned char)0xb9; break; + case XK_scaron: *buf = (unsigned char)0xba; break; + case XK_tslash: *buf = (unsigned char)0xbb; break; + case XK_zcaron: *buf = (unsigned char)0xbc; break; + case XK_umacron: *buf = (unsigned char)0xbe; break; + case XK_utilde: *buf = (unsigned char)0xf7; break; + case XK_eng: *buf = (unsigned char)0xbf; break; + case XK_kra: *buf = (unsigned char)0xff; break; + case XK_Itilde: + case XK_Kcedilla: + case XK_Iogonek: + case XK_Ncedilla: + case XK_Omacron: + case XK_Uogonek: + case XK_itilde: + case XK_kcedilla: + case XK_iogonek: + case XK_ncedilla: + case XK_omacron: + case XK_uogonek: *buf = (unsigned char)(keysym & 0xff); break; + default: count = 0; + } + } + } else if (locale_code == sLatin9 && keysym == XK_EuroSign) { + count = 1; + *buf = (unsigned char)0xa4; + } else if ((locale_code == sGreek) && + ((keysym == XK_leftsinglequotemark) || + (keysym == XK_rightsinglequotemark))) { + *buf = (unsigned char)(keysym - (XK_leftsinglequotemark - 0xa1)); + count = 1; + } + if (count>nbytes) + return nbytes; + if (count<nbytes) + buf[count]= '\0'; + return count; +} + +#ifdef XKB +static int lookup_string (event, buffer, nbytes, keysym, status) + XKeyEvent* event; + char* buffer; + int nbytes; + KeySym* keysym; + XComposeStatus* status; +{ + int ret; + unsigned ctrls = XkbGetXlibControls (event->display); + XkbSetXlibControls (event->display, + XkbLC_ForceLatin1Lookup, XkbLC_ForceLatin1Lookup); + ret = XLookupString(event, buffer, nbytes, keysym, status); + XkbSetXlibControls (event->display, ctrls, ctrls); + return ret; +} +#endif + +#define BUF_SIZE (20) + +int +_XimLookupMBText(ic, event, buffer, nbytes, keysym, status) + Xic ic; + XKeyEvent* event; + char* buffer; + int nbytes; + KeySym* keysym; + XComposeStatus* status; +{ + int count, local_count; + KeySym symbol; + struct CodesetRec *cset; + int i; + Status dummy; + Xim im = (Xim)ic->core.im; + XLCd lcd = im->core.lcd; + unsigned char local_buf[BUF_SIZE]; + unsigned char look[BUF_SIZE]; + + + /* force a latin-1 lookup for compatibility */ + count = XLOOKUPSTRING(event, (char *)buffer, nbytes, &symbol, status); + if (keysym != NULL) *keysym = symbol; + if ((nbytes == 0) || (symbol == NoSymbol)) return count; + + for (cset = NULL, i = 0; i < NUM_CODESETS; i++) { + if (strcmp (XLC_PUBLIC(lcd,encoding_name), CodesetTable[i].locale_name) == 0) { + cset = &CodesetTable[i]; + break; + } + } + if (count == 0 && cset != NULL || + (count == 1 && (symbol > 0x7f && symbol < 0xff00) && + cset != NULL && cset->locale_code != 0)) { + if ((count = _XGetCharCode(cset->locale_code, symbol, + look, sizeof look))) { + strcpy((char*) local_buf, cset->escape_seq); + local_count = strlen(cset->escape_seq); + local_buf[local_count] = look[0]; + local_count++; + local_buf[local_count] = '\0'; + if ((count = im->methods->ctstombs(ic->core.im, + (char*) local_buf, local_count, + (char *)buffer, nbytes, &dummy)) < 0) { + count = 0; + } + } + } else if (count > 1) { /* not ASCII Encoding */ + memcpy(look, (char *)buffer,count); + look[count] = '\0'; + if ((count = im->methods->ctstombs(ic->core.im, + (char*) look, count, + buffer, nbytes, &dummy)) < 0) { + count = 0; + } + } + /* + * we should make sure that if the character is a Latin1 character + * and it's on the right side, and we're in a non-Latin1 locale + * that this is a valid Latin1 character for this locale. + */ + return count; +} + +int +_XimLookupWCText(ic, event, buffer, nbytes, keysym, status) + Xic ic; + XKeyEvent* event; + wchar_t* buffer; + int nbytes; + KeySym* keysym; + XComposeStatus* status; +{ + int count, local_count; + KeySym symbol; + struct CodesetRec *cset; + int i; + Status dummy; + Xim im = (Xim)ic->core.im; + XLCd lcd = im->core.lcd; + unsigned char local_buf[BUF_SIZE]; + unsigned char look[BUF_SIZE]; + + /* force a latin-1 lookup for compatibility */ + count = XLOOKUPSTRING(event, (char *)look, nbytes, &symbol, status); + if (keysym != NULL) *keysym = symbol; + if ((nbytes == 0) || (symbol == NoSymbol)) return count; + + for (cset = NULL, i = 0; i < NUM_CODESETS; i++) { + if (strcmp (XLC_PUBLIC(lcd,encoding_name), CodesetTable[i].locale_name) == 0) { + cset = &CodesetTable[i]; + break; + } + } + if (count == 0 && cset != NULL || + (count == 1 && (symbol > 0x7f && symbol < 0xff00) && + cset != NULL && cset->locale_code != 0)) { + if ((count = _XGetCharCode(cset->locale_code, symbol, + look, sizeof look))) { + strcpy((char*) local_buf, cset->escape_seq); + local_count = strlen(cset->escape_seq); + local_buf[local_count] = look[0]; + local_count++; + local_buf[local_count] = '\0'; + if ((count = im->methods->ctstowcs(ic->core.im, + (char*) local_buf, local_count, + buffer, nbytes, &dummy)) < 0) { + count = 0; + } + } + } else if (count > 1) { + if ((count = im->methods->ctstowcs(ic->core.im, + (char*) look, count, + buffer, nbytes, &dummy)) < 0) { + count = 0; + } + } else + /* + * we should make sure that if the character is a Latin1 character + * and it's on the right side, and we're in a non-Latin1 locale + * that this is a valid Latin1 character for this locale. + */ + buffer[0] = look[0]; + + return count; +} diff --git a/src/locking.c b/src/locking.c new file mode 100644 index 00000000..96926975 --- /dev/null +++ b/src/locking.c @@ -0,0 +1,642 @@ +/* $Xorg: locking.c,v 1.5 2001/02/09 02:03:40 xorgcvs Exp $ */ +/* + +Copyright 1992, 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. + +*/ + +/* + * Author: Stephen Gildea, MIT X Consortium + * + * locking.c - multi-thread locking routines implemented in C Threads + */ + +#include "Xlibint.h" +#undef _XLockMutex +#undef _XUnlockMutex +#undef _XCreateMutex +#undef _XFreeMutex + +#ifdef XTHREADS + +#include "locking.h" +#ifdef XTHREADS_WARN +#include <stdio.h> /* for warn/debug stuff */ +#endif + +#define NUM_FREE_CVLS 4 + +/* in XOpenDis.c */ +extern int (*_XInitDisplayLock_fn)(); +extern void (*_XFreeDisplayLock_fn)(); + +/* in lcWrap.c */ +extern LockInfoPtr _Xi18n_lock; + +#ifdef WIN32 +static DWORD _X_TlsIndex = (DWORD)-1; + +_Xthread_init() +{ + if (_X_TlsIndex == (DWORD)-1) + _X_TlsIndex = TlsAlloc(); +} + +struct _xthread_waiter * +_Xthread_waiter() +{ + struct _xthread_waiter *me; + + if (!(me = TlsGetValue(_X_TlsIndex))) { + me = (struct _xthread_waiter *)xmalloc(sizeof(struct _xthread_waiter)); + me->sem = CreateSemaphore(NULL, 0, 1, NULL); + me->next = NULL; + TlsSetValue(_X_TlsIndex, me); + } + return me; +} +#endif /* WIN32 */ + +static xthread_t _Xthread_self() +{ + return xthread_self(); +} + +static LockInfoRec global_lock; +static LockInfoRec i18n_lock; + +#if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE) +static void _XLockMutex(lip,file,line) + LockInfoPtr lip; + char* file; + int line; +#else +static void _XLockMutex(lip) + LockInfoPtr lip; +#endif +{ + xmutex_lock(lip->lock); +} + +#if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE) +static void _XUnlockMutex(lip,file,line) + LockInfoPtr lip; + char* file; + int line; +#else +static void _XUnlockMutex(lip) + LockInfoPtr lip; +#endif +{ + xmutex_unlock(lip->lock); +} + +static void _XCreateMutex(lip) + LockInfoPtr lip; +{ + lip->lock = xmutex_malloc(); + if (lip->lock) { + xmutex_init(lip->lock); + xmutex_set_name(lip->lock, "Xlib"); + } +} + +static void _XFreeMutex(lip) + LockInfoPtr lip; +{ + xmutex_clear(lip->lock); + xmutex_free(lip->lock); +} + +#ifdef XTHREADS_WARN +static char *locking_file; +static int locking_line; +static xthread_t locking_thread; +static Bool xlibint_unlock = False; /* XlibInt.c may Unlock and re-Lock */ + +/* history that is useful to examine in a debugger */ +#define LOCK_HIST_SIZE 21 + +static struct { + Bool lockp; /* True for lock, False for unlock */ + xthread_t thread; + char *file; + int line; +} locking_history[LOCK_HIST_SIZE]; + +int lock_hist_loc = 0; /* next slot to fill */ + +static void _XLockDisplayWarn(dpy,file,line) + Display *dpy; + char *file; /* source file, from macro */ + int line; +{ + xthread_t self; + xthread_t old_locker; + + self = xthread_self(); + old_locker = locking_thread; + if (xthread_have_id(old_locker)) { + if (xthread_equal(old_locker, self)) + printf("Xlib ERROR: %s line %d thread %x: locking display already locked at %s line %d\n", + file, line, self, locking_file, locking_line); +#ifdef XTHREADS_DEBUG + else + printf("%s line %d: thread %x waiting on lock held by %s line %d thread %x\n", + file, line, self, + locking_file, locking_line, old_locker); +#endif /* XTHREADS_DEBUG */ + } + + xmutex_lock(dpy->lock->mutex); + + if (strcmp(file, "XlibInt.c") == 0) { + if (!xlibint_unlock) + printf("Xlib ERROR: XlibInt.c line %d thread %x locking display it did not unlock\n", + line, self); + xlibint_unlock = False; + } + +#ifdef XTHREADS_DEBUG + /* if (old_locker && old_locker != self) */ + if (strcmp("XClearArea.c", file) && strcmp("XDrSegs.c", file)) /* ico */ + printf("%s line %d: thread %x got display lock\n", file, line, self); +#endif /* XTHREADS_DEBUG */ + + locking_thread = self; + if (strcmp(file, "XlibInt.c") != 0) { + locking_file = file; + locking_line = line; + } + locking_history[lock_hist_loc].file = file; + locking_history[lock_hist_loc].line = line; + locking_history[lock_hist_loc].thread = self; + locking_history[lock_hist_loc].lockp = True; + lock_hist_loc++; + if (lock_hist_loc >= LOCK_HIST_SIZE) + lock_hist_loc = 0; +} +#endif /* XTHREADS_WARN */ + +#if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE) +static void _XUnlockDisplay(dpy,file,line) + Display *dpy; + char *file; + int line; +#else +static void _XUnlockDisplay(dpy) + Display *dpy; +#endif +{ +#ifdef XTHREADS_WARN + xthread_t self = xthread_self(); + +#ifdef XTHREADS_DEBUG + if (strcmp("XClearArea.c", file) && strcmp("XDrSegs.c", file)) /* ico */ + printf("%s line %d: thread %x unlocking display\n", file, line, self); +#endif /* XTHREADS_DEBUG */ + + if (!xthread_have_id(locking_thread)) + printf("Xlib ERROR: %s line %d thread %x: unlocking display that is not locked\n", + file, line, self); + else if (strcmp(file, "XlibInt.c") == 0) + xlibint_unlock = True; +#ifdef XTHREADS_DEBUG + else if (strcmp(file, locking_file) != 0) + /* not always an error because locking_file is not per-thread */ + printf("%s line %d: unlocking display locked from %s line %d (probably okay)\n", + file, line, locking_file, locking_line); +#endif /* XTHREADS_DEBUG */ + xthread_clear_id(locking_thread); + + locking_history[lock_hist_loc].file = file; + locking_history[lock_hist_loc].line = line; + locking_history[lock_hist_loc].thread = self; + locking_history[lock_hist_loc].lockp = False; + lock_hist_loc++; + if (lock_hist_loc >= LOCK_HIST_SIZE) + lock_hist_loc = 0; +#endif /* XTHREADS_WARN */ + xmutex_unlock(dpy->lock->mutex); +} + + +static struct _XCVList *_XCreateCVL(dpy) + Display *dpy; +{ + struct _XCVList *cvl; + + if ((cvl = dpy->lock->free_cvls) != NULL) { + dpy->lock->free_cvls = cvl->next; + dpy->lock->num_free_cvls--; + } else { + cvl = (struct _XCVList *)Xmalloc(sizeof(struct _XCVList)); + if (!cvl) + return NULL; + cvl->cv = xcondition_malloc(); + if (!cvl->cv) { + Xfree(cvl); + return NULL; + } + xcondition_init(cvl->cv); + xcondition_set_name(cvl->cv, "Xlib read queue"); + } + cvl->next = NULL; + return cvl; +} + +/* Put ourselves on the queue to read the connection. + Allocates and returns a queue element. */ + +static struct _XCVList * +_XPushReader(dpy, tail) + Display *dpy; + struct _XCVList ***tail; +{ + struct _XCVList *cvl; + + cvl = _XCreateCVL(dpy); +#ifdef XTHREADS_DEBUG + printf("_XPushReader called in thread %x, pushing %x\n", + xthread_self(), cvl); +#endif + **tail = cvl; + *tail = &cvl->next; + return cvl; +} + +/* signal the next thread waiting to read the connection */ + +static void _XPopReader(dpy, list, tail) + Display *dpy; + struct _XCVList **list; + struct _XCVList ***tail; +{ + register struct _XCVList *front = *list; + +#ifdef XTHREADS_DEBUG + printf("_XPopReader called in thread %x, popping %x\n", + xthread_self(), front); +#endif + + if (dpy->flags & XlibDisplayProcConni) + /* we never added ourself in the first place */ + return; + + if (front) { /* check "front" for paranoia */ + *list = front->next; + if (*tail == &front->next) /* did we free the last elt? */ + *tail = list; + if (dpy->lock->num_free_cvls < NUM_FREE_CVLS) { + front->next = dpy->lock->free_cvls; + dpy->lock->free_cvls = front; + dpy->lock->num_free_cvls++; + } else { + xcondition_clear(front->cv); + Xfree((char *)front->cv); + Xfree((char *)front); + } + } + + /* signal new front after it is in place */ + if ((dpy->lock->reply_first = (dpy->lock->reply_awaiters != NULL))) { + ConditionSignal(dpy, dpy->lock->reply_awaiters->cv); + } else if (dpy->lock->event_awaiters) { + ConditionSignal(dpy, dpy->lock->event_awaiters->cv); + } +} + +#if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE) +static void _XConditionWait(cv, mutex,file,line) + xcondition_t cv; + xmutex_t mutex; + char *file; + int line; +#else +static void _XConditionWait(cv, mutex) + xcondition_t cv; + xmutex_t mutex; +#endif +{ +#ifdef XTHREADS_WARN + xthread_t self = xthread_self(); + char *old_file = locking_file; + int old_line = locking_line; + +#ifdef XTHREADS_DEBUG + printf("line %d thread %x in condition wait\n", line, self); +#endif + xthread_clear_id(locking_thread); + + locking_history[lock_hist_loc].file = file; + locking_history[lock_hist_loc].line = line; + locking_history[lock_hist_loc].thread = self; + locking_history[lock_hist_loc].lockp = False; + lock_hist_loc++; + if (lock_hist_loc >= LOCK_HIST_SIZE) + lock_hist_loc = 0; +#endif /* XTHREADS_WARN */ + + xcondition_wait(cv, mutex); + +#ifdef XTHREADS_WARN + locking_thread = self; + locking_file = old_file; + locking_line = old_line; + + locking_history[lock_hist_loc].file = file; + locking_history[lock_hist_loc].line = line; + locking_history[lock_hist_loc].thread = self; + locking_history[lock_hist_loc].lockp = True; + lock_hist_loc++; + if (lock_hist_loc >= LOCK_HIST_SIZE) + lock_hist_loc = 0; +#ifdef XTHREADS_DEBUG + printf("line %d thread %x was signaled\n", line, self); +#endif /* XTHREADS_DEBUG */ +#endif /* XTHREADS_WARN */ +} + +#if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE) +static void _XConditionSignal(cv,file,line) + xcondition_t cv; + char *file; + int line; +#else +static void _XConditionSignal(cv) + xcondition_t cv; +#endif +{ +#ifdef XTHREADS_WARN +#ifdef XTHREADS_DEBUG + printf("line %d thread %x is signalling\n", line, xthread_self()); +#endif +#endif + xcondition_signal(cv); +} + + +#if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE) +static void _XConditionBroadcast(cv,file,line) + xcondition_t cv; + char *file; + int line; +#else +static void _XConditionBroadcast(cv) + xcondition_t cv; +#endif +{ +#ifdef XTHREADS_WARN +#ifdef XTHREADS_DEBUG + printf("line %d thread %x is broadcasting\n", line, xthread_self()); +#endif +#endif + xcondition_broadcast(cv); +} + + +static void _XFreeDisplayLock(dpy) + Display *dpy; +{ + struct _XCVList *cvl; + + if (dpy->lock != NULL) { + if (dpy->lock->mutex != NULL) { + xmutex_clear(dpy->lock->mutex); + xmutex_free(dpy->lock->mutex); + } + if (dpy->lock->cv != NULL) { + xcondition_clear(dpy->lock->cv); + xcondition_free(dpy->lock->cv); + } + if (dpy->lock->writers != NULL) { + xcondition_clear(dpy->lock->writers); + xcondition_free(dpy->lock->writers); + } + while ((cvl = dpy->lock->free_cvls)) { + dpy->lock->free_cvls = cvl->next; + xcondition_clear(cvl->cv); + Xfree((char *)cvl->cv); + Xfree((char *)cvl); + } + Xfree((char *)dpy->lock); + dpy->lock = NULL; + } + if (dpy->lock_fns != NULL) { + Xfree((char *)dpy->lock_fns); + dpy->lock_fns = NULL; + } +} + +/* + * wait for thread with user-level display lock to release it. + */ + +static void _XDisplayLockWait(dpy) + Display *dpy; +{ + xthread_t self; + + while (dpy->lock->locking_level > 0) { + self = xthread_self(); + if (xthread_equal(dpy->lock->locking_thread, self)) + break; + ConditionWait(dpy, dpy->lock->cv); + } +} + +#if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE) +static void _XLockDisplay(dpy, file, line) + Display *dpy; + char *file; /* source file, from macro */ + int line; +#else +static void _XLockDisplay(dpy) + Display *dpy; +#endif +{ +#ifdef XTHREADS_WARN + _XLockDisplayWarn(dpy, file, line); +#else + xmutex_lock(dpy->lock->mutex); +#endif + if (dpy->lock->locking_level > 0) + _XDisplayLockWait(dpy); +} + +/* + * _XReply is allowed to exit from select/poll and clean up even if a + * user-level lock is in force, so it uses this instead of _XFancyLockDisplay. + */ +#if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE) +static void _XInternalLockDisplay(dpy, wskip, file, line) + Display *dpy; + Bool wskip; + char *file; /* source file, from macro */ + int line; +#else +static void _XInternalLockDisplay(dpy, wskip) + Display *dpy; + Bool wskip; +#endif +{ +#ifdef XTHREADS_WARN + _XLockDisplayWarn(dpy, file, line); +#else + xmutex_lock(dpy->lock->mutex); +#endif + if (!wskip && dpy->lock->locking_level > 0) + _XDisplayLockWait(dpy); +} + +#if NeedFunctionPrototypes +static void _XUserLockDisplay( + register Display* dpy) +#else +static void _XUserLockDisplay(dpy) + register Display* dpy; +#endif +{ + if (++dpy->lock->locking_level == 1) { + dpy->lock->lock_wait = _XDisplayLockWait; + dpy->lock->locking_thread = xthread_self(); + } +} + +#if NeedFunctionPrototypes +void _XUserUnlockDisplay( + register Display* dpy) +#else +void _XUserUnlockDisplay(dpy) + register Display* dpy; +#endif +{ + if (dpy->lock->locking_level > 0 && --dpy->lock->locking_level == 0) { + /* signal other threads that might be waiting in XLockDisplay */ + ConditionBroadcast(dpy, dpy->lock->cv); + dpy->lock->lock_wait = NULL; + xthread_clear_id(dpy->lock->locking_thread); + } +} + +/* returns 0 if initialized ok, -1 if unable to allocate + a mutex or other memory */ + +static int _XInitDisplayLock(dpy) + Display *dpy; +{ + dpy->lock_fns = (struct _XLockPtrs*)Xmalloc(sizeof(struct _XLockPtrs)); + if (dpy->lock_fns == NULL) + return -1; + dpy->lock = (struct _XLockInfo *)Xmalloc(sizeof(struct _XLockInfo)); + if (dpy->lock == NULL) { + _XFreeDisplayLock(dpy); + return -1; + } + dpy->lock->cv = xcondition_malloc(); + dpy->lock->mutex = xmutex_malloc(); + dpy->lock->writers = xcondition_malloc(); + if (!dpy->lock->cv || !dpy->lock->mutex || !dpy->lock->writers) { + _XFreeDisplayLock(dpy); + return -1; + } + + dpy->lock->reply_bytes_left = 0; + dpy->lock->reply_was_read = False; + dpy->lock->reply_awaiters = NULL; + dpy->lock->reply_awaiters_tail = &dpy->lock->reply_awaiters; + dpy->lock->event_awaiters = NULL; + dpy->lock->event_awaiters_tail = &dpy->lock->event_awaiters; + dpy->lock->reply_first = False; + dpy->lock->locking_level = 0; + dpy->lock->num_free_cvls = 0; + dpy->lock->free_cvls = NULL; + xthread_clear_id(dpy->lock->locking_thread); + xthread_clear_id(dpy->lock->reading_thread); + xthread_clear_id(dpy->lock->conni_thread); + xmutex_init(dpy->lock->mutex); + xmutex_set_name(dpy->lock->mutex, "Xlib Display"); + xcondition_init(dpy->lock->cv); + xcondition_set_name(dpy->lock->cv, "XLockDisplay"); + xcondition_init(dpy->lock->writers); + xcondition_set_name(dpy->lock->writers, "Xlib wait for writable"); + dpy->lock_fns->lock_display = _XLockDisplay; + dpy->lock->internal_lock_display = _XInternalLockDisplay; + dpy->lock_fns->unlock_display = _XUnlockDisplay; + dpy->lock->user_lock_display = _XUserLockDisplay; + dpy->lock->user_unlock_display = _XUserUnlockDisplay; + dpy->lock->pop_reader = _XPopReader; + dpy->lock->push_reader = _XPushReader; + dpy->lock->condition_wait = _XConditionWait; + dpy->lock->condition_signal = _XConditionSignal; + dpy->lock->condition_broadcast = _XConditionBroadcast; + dpy->lock->create_cvl = _XCreateCVL; + dpy->lock->lock_wait = NULL; /* filled in by XLockDisplay() */ + + return 0; +} + + +Status XInitThreads() +{ + if (_Xglobal_lock) + return 1; +#ifdef xthread_init + xthread_init(); /* return value? */ +#endif + if (!(global_lock.lock = xmutex_malloc())) + return 0; + if (!(i18n_lock.lock = xmutex_malloc())) { + xmutex_free(global_lock.lock); + global_lock.lock = NULL; + return 0; + } + _Xglobal_lock = &global_lock; + xmutex_init(_Xglobal_lock->lock); + xmutex_set_name(_Xglobal_lock->lock, "Xlib global"); + _Xi18n_lock = &i18n_lock; + xmutex_init(_Xi18n_lock->lock); + xmutex_set_name(_Xi18n_lock->lock, "Xlib i18n"); + _XLockMutex_fn = _XLockMutex; + _XUnlockMutex_fn = _XUnlockMutex; + _XCreateMutex_fn = _XCreateMutex; + _XFreeMutex_fn = _XFreeMutex; + _XInitDisplayLock_fn = _XInitDisplayLock; + _XFreeDisplayLock_fn = _XFreeDisplayLock; + _Xthread_self_fn = _Xthread_self; + +#ifdef XTHREADS_WARN +#ifdef XTHREADS_DEBUG + setlinebuf(stdout); /* for debugging messages */ +#endif +#endif + + return 1; +} + +#else /* XTHREADS */ +Status XInitThreads() +{ + return 0; +} +#endif /* XTHREADS */ diff --git a/src/locking.h b/src/locking.h new file mode 100644 index 00000000..2b3afd32 --- /dev/null +++ b/src/locking.h @@ -0,0 +1,173 @@ +/* $Xorg: locking.h,v 1.4 2001/02/09 02:03:40 xorgcvs Exp $ */ +/* + +Copyright 1992, 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. + +*/ + +/* + * Author: Stephen Gildea, MIT X Consortium + * + * locking.h - data types for C Threads locking. + * Used by XlibInt.c, locking.c, LockDis.c + */ + +#ifndef _X_locking_H_ +#define _X_locking_H_ + +#define xmalloc(s) Xmalloc(s) +#define xfree(s) Xfree(s) +#include <X11/Xthreads.h> + +struct _XCVList { + xcondition_t cv; + xReply *buf; + struct _XCVList *next; +}; + +extern xthread_t (*_Xthread_self_fn)( /* in XlibInt.c */ +#if NeedFunctionPrototypes + void +#endif +); + +/* Display->lock is a pointer to one of these */ + +struct _XLockInfo { + xmutex_t mutex; /* mutex for critical sections */ + int reply_bytes_left; /* nbytes of the reply still to read */ + Bool reply_was_read; /* _XReadEvents read a reply for _XReply */ + struct _XCVList *reply_awaiters; /* list of CVs for _XReply */ + struct _XCVList **reply_awaiters_tail; + struct _XCVList *event_awaiters; /* list of CVs for _XReadEvents */ + struct _XCVList **event_awaiters_tail; + Bool reply_first; /* who may read, reply queue or event queue */ + /* for XLockDisplay */ + int locking_level; /* how many times into XLockDisplay we are */ + xthread_t locking_thread; /* thread that did XLockDisplay */ + xcondition_t cv; /* wait if another thread has XLockDisplay */ + xthread_t reading_thread; /* cache */ + xthread_t conni_thread; /* thread in XProcessInternalConnection */ + xcondition_t writers; /* wait for writable */ + int num_free_cvls; + struct _XCVList *free_cvls; + /* used only in XlibInt.c */ + void (*pop_reader)( +#if NeedNestedPrototypes + Display* /* dpy */, + struct _XCVList** /* list */, + struct _XCVList*** /* tail */ +#endif + ); + struct _XCVList *(*push_reader)( +#if NeedNestedPrototypes + Display * /* dpy */, + struct _XCVList*** /* tail */ +#endif + ); + void (*condition_wait)( +#if NeedNestedPrototypes + xcondition_t /* cv */, + xmutex_t /* mutex */ +#if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE) + , char* /* file */, + int /* line */ +#endif +#endif + ); + void (*internal_lock_display)( +#if NeedNestedPrototypes + Display* /* dpy */, + Bool /* wskip */ +#if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE) + , char* /* file */, + int /* line */ +#endif +#endif + ); + /* used in XlibInt.c and locking.c */ + void (*condition_signal)( +#if NeedNestedPrototypes + xcondition_t /* cv */ +#if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE) + , char* /* file */, + int /* line */ +#endif +#endif + ); + void (*condition_broadcast)( +#if NeedNestedPrototypes + xcondition_t /* cv */ +#if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE) + , char* /* file */, + int /* line */ +#endif +#endif + ); + /* used in XlibInt.c and XLockDis.c */ + void (*lock_wait)( +#if NeedNestedPrototypes + Display* /* dpy */ +#endif + ); + void (*user_lock_display)( +#if NeedNestedPrototypes + Display* /* dpy */ +#endif + ); + void (*user_unlock_display)( +#if NeedNestedPrototypes + Display* /* dpy */ +#endif + ); + struct _XCVList *(*create_cvl)( +#if NeedNestedPrototypes + Display * /* dpy */ +#endif + ); +}; + +#define UnlockNextEventReader(d) if ((d)->lock) \ + (*(d)->lock->pop_reader)((d),&(d)->lock->event_awaiters,&(d)->lock->event_awaiters_tail) + +#if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE) +#define ConditionWait(d,c) if ((d)->lock) \ + (*(d)->lock->condition_wait)(c, (d)->lock->mutex,__FILE__,__LINE__) +#define ConditionSignal(d,c) if ((d)->lock) \ + (*(d)->lock->condition_signal)(c,__FILE__,__LINE__) +#define ConditionBroadcast(d,c) if ((d)->lock) \ + (*(d)->lock->condition_broadcast)(c,__FILE__,__LINE__) +#else +#define ConditionWait(d,c) if ((d)->lock) \ + (*(d)->lock->condition_wait)(c, (d)->lock->mutex) +#define ConditionSignal(d,c) if ((d)->lock) \ + (*(d)->lock->condition_signal)(c) +#define ConditionBroadcast(d,c) if ((d)->lock) \ + (*(d)->lock->condition_broadcast)(c) +#endif + +typedef struct _LockInfoRec { + xmutex_t lock; +} LockInfoRec; + +#endif /* _X_locking_H_ */ diff --git a/src/poly.h b/src/poly.h new file mode 100644 index 00000000..0d82443c --- /dev/null +++ b/src/poly.h @@ -0,0 +1,295 @@ +/* $Xorg: poly.h,v 1.4 2001/02/09 02:03:40 xorgcvs Exp $ */ +/************************************************************************ + +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. + +************************************************************************/ + +/* + * This file contains a few macros to help track + * the edge of a filled object. The object is assumed + * to be filled in scanline order, and thus the + * algorithm used is an extension of Bresenham's line + * drawing algorithm which assumes that y is always the + * major axis. + * Since these pieces of code are the same for any filled shape, + * it is more convenient to gather the library in one + * place, but since these pieces of code are also in + * the inner loops of output primitives, procedure call + * overhead is out of the question. + * See the author for a derivation if needed. + */ + + +/* + * In scan converting polygons, we want to choose those pixels + * which are inside the polygon. Thus, we add .5 to the starting + * x coordinate for both left and right edges. Now we choose the + * first pixel which is inside the pgon for the left edge and the + * first pixel which is outside the pgon for the right edge. + * Draw the left pixel, but not the right. + * + * How to add .5 to the starting x coordinate: + * If the edge is moving to the right, then subtract dy from the + * error term from the general form of the algorithm. + * If the edge is moving to the left, then add dy to the error term. + * + * The reason for the difference between edges moving to the left + * and edges moving to the right is simple: If an edge is moving + * to the right, then we want the algorithm to flip immediately. + * If it is moving to the left, then we don't want it to flip until + * we traverse an entire pixel. + */ +#define BRESINITPGON(dy, x1, x2, xStart, d, m, m1, incr1, incr2) { \ + int dx; /* local storage */ \ +\ + /* \ + * if the edge is horizontal, then it is ignored \ + * and assumed not to be processed. Otherwise, do this stuff. \ + */ \ + if ((dy) != 0) { \ + xStart = (x1); \ + dx = (x2) - xStart; \ + if (dx < 0) { \ + m = dx / (dy); \ + m1 = m - 1; \ + incr1 = -2 * dx + 2 * (dy) * m1; \ + incr2 = -2 * dx + 2 * (dy) * m; \ + d = 2 * m * (dy) - 2 * dx - 2 * (dy); \ + } else { \ + m = dx / (dy); \ + m1 = m + 1; \ + incr1 = 2 * dx - 2 * (dy) * m1; \ + incr2 = 2 * dx - 2 * (dy) * m; \ + d = -2 * m * (dy) + 2 * dx; \ + } \ + } \ +} + +#define BRESINCRPGON(d, minval, m, m1, incr1, incr2) { \ + if (m1 > 0) { \ + if (d > 0) { \ + minval += m1; \ + d += incr1; \ + } \ + else { \ + minval += m; \ + d += incr2; \ + } \ + } else {\ + if (d >= 0) { \ + minval += m1; \ + d += incr1; \ + } \ + else { \ + minval += m; \ + d += incr2; \ + } \ + } \ +} + + +/* + * This structure contains all of the information needed + * to run the bresenham algorithm. + * The variables may be hardcoded into the declarations + * instead of using this structure to make use of + * register declarations. + */ +typedef struct { + int minor_axis; /* minor axis */ + int d; /* decision variable */ + int m, m1; /* slope and slope+1 */ + int incr1, incr2; /* error increments */ +} BRESINFO; + + +#define BRESINITPGONSTRUCT(dmaj, min1, min2, bres) \ + BRESINITPGON(dmaj, min1, min2, bres.minor_axis, bres.d, \ + bres.m, bres.m1, bres.incr1, bres.incr2) + +#define BRESINCRPGONSTRUCT(bres) \ + BRESINCRPGON(bres.d, bres.minor_axis, bres.m, bres.m1, bres.incr1, bres.incr2) + + + +/* + * These are the data structures needed to scan + * convert regions. Two different scan conversion + * methods are available -- the even-odd method, and + * the winding number method. + * The even-odd rule states that a point is inside + * the polygon if a ray drawn from that point in any + * direction will pass through an odd number of + * path segments. + * By the winding number rule, a point is decided + * to be inside the polygon if a ray drawn from that + * point in any direction passes through a different + * number of clockwise and counter-clockwise path + * segments. + * + * These data structures are adapted somewhat from + * the algorithm in (Foley/Van Dam) for scan converting + * polygons. + * The basic algorithm is to start at the top (smallest y) + * of the polygon, stepping down to the bottom of + * the polygon by incrementing the y coordinate. We + * keep a list of edges which the current scanline crosses, + * sorted by x. This list is called the Active Edge Table (AET) + * As we change the y-coordinate, we update each entry in + * in the active edge table to reflect the edges new xcoord. + * This list must be sorted at each scanline in case + * two edges intersect. + * We also keep a data structure known as the Edge Table (ET), + * which keeps track of all the edges which the current + * scanline has not yet reached. The ET is basically a + * list of ScanLineList structures containing a list of + * edges which are entered at a given scanline. There is one + * ScanLineList per scanline at which an edge is entered. + * When we enter a new edge, we move it from the ET to the AET. + * + * From the AET, we can implement the even-odd rule as in + * (Foley/Van Dam). + * The winding number rule is a little trickier. We also + * keep the EdgeTableEntries in the AET linked by the + * nextWETE (winding EdgeTableEntry) link. This allows + * the edges to be linked just as before for updating + * purposes, but only uses the edges linked by the nextWETE + * link as edges representing spans of the polygon to + * drawn (as with the even-odd rule). + */ + +/* + * for the winding number rule + */ +#define CLOCKWISE 1 +#define COUNTERCLOCKWISE -1 + +typedef struct _EdgeTableEntry { + int ymax; /* ycoord at which we exit this edge. */ + BRESINFO bres; /* Bresenham info to run the edge */ + struct _EdgeTableEntry *next; /* next in the list */ + struct _EdgeTableEntry *back; /* for insertion sort */ + struct _EdgeTableEntry *nextWETE; /* for winding num rule */ + int ClockWise; /* flag for winding number rule */ +} EdgeTableEntry; + + +typedef struct _ScanLineList{ + int scanline; /* the scanline represented */ + EdgeTableEntry *edgelist; /* header node */ + struct _ScanLineList *next; /* next in the list */ +} ScanLineList; + + +typedef struct { + int ymax; /* ymax for the polygon */ + int ymin; /* ymin for the polygon */ + ScanLineList scanlines; /* header node */ +} EdgeTable; + + +/* + * Here is a struct to help with storage allocation + * so we can allocate a big chunk at a time, and then take + * pieces from this heap when we need to. + */ +#define SLLSPERBLOCK 25 + +typedef struct _ScanLineListBlock { + ScanLineList SLLs[SLLSPERBLOCK]; + struct _ScanLineListBlock *next; +} ScanLineListBlock; + + + +/* + * + * a few macros for the inner loops of the fill code where + * performance considerations don't allow a procedure call. + * + * Evaluate the given edge at the given scanline. + * If the edge has expired, then we leave it and fix up + * the active edge table; otherwise, we increment the + * x value to be ready for the next scanline. + * The winding number rule is in effect, so we must notify + * the caller when the edge has been removed so he + * can reorder the Winding Active Edge Table. + */ +#define EVALUATEEDGEWINDING(pAET, pPrevAET, y, fixWAET) { \ + if (pAET->ymax == y) { /* leaving this edge */ \ + pPrevAET->next = pAET->next; \ + pAET = pPrevAET->next; \ + fixWAET = 1; \ + if (pAET) \ + pAET->back = pPrevAET; \ + } \ + else { \ + BRESINCRPGONSTRUCT(pAET->bres); \ + pPrevAET = pAET; \ + pAET = pAET->next; \ + } \ +} + + +/* + * Evaluate the given edge at the given scanline. + * If the edge has expired, then we leave it and fix up + * the active edge table; otherwise, we increment the + * x value to be ready for the next scanline. + * The even-odd rule is in effect. + */ +#define EVALUATEEDGEEVENODD(pAET, pPrevAET, y) { \ + if (pAET->ymax == y) { /* leaving this edge */ \ + pPrevAET->next = pAET->next; \ + pAET = pPrevAET->next; \ + if (pAET) \ + pAET->back = pPrevAET; \ + } \ + else { \ + BRESINCRPGONSTRUCT(pAET->bres); \ + pPrevAET = pAET; \ + pAET = pAET->next; \ + } \ +} diff --git a/src/udcInf.c b/src/udcInf.c new file mode 100644 index 00000000..c1392bed --- /dev/null +++ b/src/udcInf.c @@ -0,0 +1,711 @@ +/* $Xorg: udcInf.c,v 1.7 2001/02/09 02:03:40 xorgcvs Exp $ */ +/* +Copyright 1996, 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 1995 by FUJITSU LIMITED + * This is source code modified by FUJITSU LIMITED under the Joint + * Development Agreement for the CDE/Motif PST. + * + * Modifier: Takanori Tateno FUJITSU LIMITED + * + */ +#include <stdio.h> +#include <locale.h> +#include <Xlib.h> +#include <Xlibint.h> +#include <Xlcint.h> +#include <XlcPubI.h> +#include <XlcGeneric.h> +#include <XomGeneric.h> + +/* + external symbols +*/ +extern FontData read_EncodingInfo(); +extern int _xudc_get_codeset(); + +extern int _xudc_utyderror ; +extern int _xudc_utyerror ; + +extern unsigned long _xudc_utyerrno ; + +#define _XUDC_ERROR -1 + + +/* + UDC structure define +*/ +typedef struct __XUDCGlyphRegion { + unsigned long start; + unsigned long end; +} _XUDCGlyphRegion ; + +/* + * "code" no jyoui "i" byte me wo "unsigned char" toshite kaesu. + */ +static unsigned char getbyte(code,i) +unsigned long code; +int i; +{ + unsigned long byteL; + unsigned char byte; + byteL = code >> (8*(3-i)); + byte = (unsigned char)(0x000000ff & byteL); + return(byte); +} +/* + get codeset which described by charset_str and locale. + for examples ... + locale : ja_JP + charset_str : JISX0208.1983-0 +*/ + +_xudc_get_codeset(locale,charset_str,codeset,num_codeset) +char *locale; +char *charset_str; +int **codeset; +int *num_codeset; +{ + XLCdRec lcdrec; + XLCd lcd; + XLCdPublicRec xlcdp; + XPointer rdb; + int num = 0,count,num_ret=0,i,*ret; + char **value,buf[128],*ptr; + + + _xudc_utyderror = 0; + _xudc_utyerror = 0; + + if((locale == NULL) || (charset_str == NULL)){ + _xudc_utyerror = 5; + _xudc_utyderror = 1; + _xudc_utyerrno = 0x04 ; + return(_XUDC_ERROR); + } + if(codeset == NULL){ + _xudc_utyerror = 5; + _xudc_utyderror = 2; + _xudc_utyerrno = 0x04 ; + return(_XUDC_ERROR); + } + + /* create XLCd */ + xlcdp.pub.siname = locale; + lcdrec.core = (XLCdCore)&xlcdp; + lcd = &lcdrec; + /* create X RDB (X NLS DB) */ + rdb = _XlcCreateLocaleDataBase(lcd); + if(rdb == NULL){ + _xudc_utyerror = 1; + _xudc_utyerrno = 0x15 ; + return(_XUDC_ERROR); + } + + for(num=0;;num++){ + /* XLC_FONTSET */ + sprintf(buf, "fs%d.font.primary", num); + _XlcGetLocaleDataBase(lcd, "XLC_FONTSET", buf, &value, &count); + if(count < 1){ + break ; + } + for(i=0;i<count;i++){ + if (strlen(value[i]) >= sizeof(buf)) + continue; + strcpy(buf,value[i]); + ptr = (char *)strchr(buf,(int)':'); + *ptr = 0; + if(!_XlcCompareISOLatin1(charset_str,buf)){ + num_ret += 1; + if(num_ret == 1){ + ret = (int *)Xmalloc(sizeof(int)); + } else { + int *prev_ret = ret; + + ret = + (int *)Xrealloc(ret,num_ret*sizeof(int)); + if (ret == NULL){ + Xfree(prev_ret); + } + } + if(ret == NULL){ + _xudc_utyerrno = 0x03 ; + return(_XUDC_ERROR); + } + ret[num_ret-1]=num; + break ; + } + } + } + if(num_ret == 0){ + *num_codeset = 0; + *codeset = NULL; + return (0xff); + } + + *num_codeset = num_ret; + *codeset = ret; + return 0; +} + +static Bool gi_to_vgi(gi,vgi,scope) +unsigned long gi,*vgi; +FontScope scope; +{ + if(scope->shift_direction == (unsigned long)'+'){ + gi -= scope->shift; + } else { + gi += scope->shift; + } + if(gi >= scope->start && gi <= scope->end){ + *vgi = gi; + return(True); + } + return(False); +} + +static void shift_area(udc,scope) +_XUDCGlyphRegion *udc; +FontScope scope; +{ + if(scope->shift_direction == (unsigned long)'+'){ + udc->start += scope->shift; + udc->end += scope->shift; + } else { + udc->start -= scope->shift; + udc->end -= scope->shift; + } +} + +/* + get UDC area with glyph index. + for examples ... + locale : ja_JP + charset_str : JISX0208.1983-0 +*/ +_XUDCGetUDCGIArea(locale,codeset,charset_str,gr,num_gr) +char *locale; +int codeset; +char *charset_str; +_XUDCGlyphRegion **gr; +int *num_gr; +{ + XLCdRec lcdrec; + XLCd lcd; + XLCdPublicRec xlcdp; + XPointer rdb; + _XUDCGlyphRegion *udc; + int num = 0,count,num_ret=0; + int i,j,k; + char **value,buf[128],ptr; + FontData font_data; + + + _xudc_utyderror = 0; + _xudc_utyerror = 0; + _xudc_utyerrno = 0x00 ; + + if((locale == NULL) || (charset_str == NULL)){ + _xudc_utyerror = 5; + _xudc_utyderror = 1; + _xudc_utyerrno = 0x04; + _xudc_utyerrno |= (0x0b<<8) ; + return(_XUDC_ERROR); + } + if(gr == NULL){ + _xudc_utyerror = 5; + _xudc_utyderror = 1; + _xudc_utyerrno = 0x04; + _xudc_utyerrno |= (0x0b<<8) ; + return(_XUDC_ERROR); + } + if(num_gr == NULL){ + _xudc_utyerror = 5; + _xudc_utyderror = 2; + _xudc_utyerrno = 0x04; + _xudc_utyerrno |= (0x0b<<8) ; + return(_XUDC_ERROR); + } + + /* create XLCd */ + xlcdp.pub.siname = locale; + lcdrec.core = (XLCdCore)&xlcdp; + lcd = &lcdrec; + /* create X RDB (X NLS DB) */ + rdb = _XlcCreateLocaleDataBase(lcd); + if(rdb == NULL){ + _xudc_utyerror = 1; + _xudc_utyerrno = 0x15 ; + _xudc_utyerrno |= (0x0b<<8) ; + return(_XUDC_ERROR); + } + udc = NULL; + + /* XLC_FONTSET */ + sprintf(buf, "fs%d.charset.udc_area", codeset-1); + _XlcGetLocaleDataBase(lcd, "XLC_FONTSET", buf, &value, &count); + if(count > 0){ + udc = (_XUDCGlyphRegion *)Xmalloc(count * sizeof(_XUDCGlyphRegion)); + if(udc == NULL){ + _xudc_utyerrno = 0x03 ; + _xudc_utyerrno |= (0x0b<<8) ; + return(_XUDC_ERROR); + } + for(i=0;i<count;i++){ + sscanf(value[i],"\\x%lx,\\x%lx", &(udc[i].start), &(udc[i].end)); + } + } + + *num_gr = count; + + sprintf(buf, "fs%d.font.primary", codeset-1); + _XlcGetLocaleDataBase(lcd, "XLC_FONTSET", buf, &value, &count); + if(count > 0){ + font_data = read_EncodingInfo(count,value); + for(i=0;i<count;i++){ + if( !_XlcCompareISOLatin1(font_data[i].name,charset_str)){ + for(j=0;j<(*num_gr);j++){ + for(k=0;k<font_data[i].scopes_num;k++){ + if(udc[j].start == font_data[i].scopes[k].start + && font_data[i].scopes[k].shift){ + shift_area(&udc[j],&(font_data[i].scopes[k])); + } + } + } + } + } + } + + *gr = udc; + return 0; +} + +/* + * Code convert wo tomonau UDC area no kakutoku + * GetUDCCPArea() / glyph_to_code() + * + */ + +static int +_xudc_gi_to_vgi(lcd,locale,charset_str,codeset,gi,vgi,charsetname,size) +XLCd lcd; +char *locale; +char *charset_str; +int codeset; +unsigned long gi; +unsigned long *vgi; +char *charsetname; +int size; +{ + _XUDCGlyphRegion *udc; + int num = 0,count,num_ret=0; + int i,j,k; + char **value,buf[128],ptr; + FontData font_data; + + + sprintf(buf, "fs%d.charset.name", codeset-1); + _XlcGetLocaleDataBase(lcd, "XLC_FONTSET", buf, &value, &count); + if(count > 0){ + strcpy(charsetname,value[0]); + } + if (count >= size) + return False; + sprintf(buf, "fs%d.font.primary", codeset-1); + _XlcGetLocaleDataBase(lcd, "XLC_FONTSET", buf, &value, &count); + if(count > 0){ + font_data = read_EncodingInfo(count,value); + for(i=0;i<count;i++){ + if( !_XlcCompareISOLatin1(font_data[i].name,charset_str)){ + for(k=0;k<font_data[i].scopes_num;k++){ + if( gi_to_vgi(gi,vgi,&(font_data[i].scopes[k])) == True){ + return(True); + } + } + } + } + } +/* + free_fontdata(font_data); +*/ + *vgi = gi; + return(True); +} + +Bool non_standard(lcd,charset) +XLCd lcd; +XlcCharSet charset; +{ + char buf[256]; + int count,i; + char **value; + if(charset->ct_sequence == NULL){ + return(False); + } + for(i=0;;i++){ + sprintf(buf, "csd%d.charset_name", i); + _XlcGetLocaleDataBase(lcd, "XLC_CHARSET_DEFINE", buf, &value, &count); + if(count > 0){ + if(!_XlcNCompareISOLatin1(value[0], + charset->name,strlen(value[0])) ){ + return(True); + } + } else { + return(False); + } + } +} + +static Bool +make_none_standard(from,charset,src,size) +char *from; +XlcCharSet charset; +char *src; +int size; +{ + int name_len,seq_len,i; + name_len = 2 + strlen(charset->encoding_name) + 1; + seq_len = strlen(charset->ct_sequence); + if (name_len + seq_len + strlen(src) >= size) + return False; + strcpy(from,charset->ct_sequence); + from[seq_len] = name_len / 128 + 128; + from[seq_len+1] = name_len % 128 + 128; + strcpy(&from[seq_len + 2],charset->encoding_name); + from[seq_len+name_len-1] = 0x02; /* STX */ + strcpy(&from[seq_len + name_len],src); + return True; +} +int +_xudc_glyph_to_code(locale,charset_str,codeset,glyph_index,codepoint) +char *locale; +char *charset_str; +int codeset; +unsigned long glyph_index; +unsigned long *codepoint; +{ + XLCd lcd; + unsigned char *from; int from_left; + unsigned char *to ; int to_left = 10; + unsigned char *dst; + unsigned char byte; + unsigned long from32[25]; + unsigned long to32[25]; + int i,j; + char tmp[256],charsetname[256],src[10]; + XlcConv conv; + XlcCharSet charset; + XPointer args[2]; + + from = (unsigned char *)from32; + to = (unsigned char *)to32; + dst = (unsigned char *)to32; + + memset(dst,0,25); + + lcd = (XLCd)_XlcGenericLoader(locale); + + if (!_xudc_gi_to_vgi(lcd,locale,charset_str,codeset, + glyph_index,&glyph_index,charsetname,sizeof(charsetname))) + return(_XUDC_ERROR); + + for(i=0,j=0;i<4;i++){ + byte = getbyte(glyph_index,i); + if(byte){ + src[j] = byte; + j ++; + } + } + src[j] = 0; + + + /* get charset */ +/* + sprintf(tmp,"%s%s",charset_str,":GL"); + charset_name = strdup(tmp); +*/ + charset = _XlcGetCharSet(charsetname); + if(charset == NULL){ + _xudc_utyerrno = 0x16 ; + return(_XUDC_ERROR); + } + /* make ct */ + if( non_standard(lcd,charset)) { + if (!make_none_standard(from,charset,src,sizeof(from32))) + return(_XUDC_ERROR); + } else if(charset->ct_sequence){ + if (strlen(charset->ct_sequence) + strlen(src) >= sizeof(from32)) + return(_XUDC_ERROR); + sprintf((char *)from,"%s%s",charset->ct_sequence,src); + } else { + sprintf((char *)from,"%s\0",src); + } + /* compound text -> multi byte */ + conv = _XlcOpenConverter(lcd, XlcNCompoundText, lcd, XlcNMultiByte); + from_left = strlen((char *)from); + _XlcConvert(conv,(XPointer *)&from,&from_left, + (XPointer *)&to, &to_left,args,0); + _XlcCloseConverter(conv); + _XlcDestroyLC(lcd); + + *codepoint = 0; + for(i=0;dst[i];i++){ + *codepoint = ((*codepoint << 8) | dst[i]) ; + } + return(0); +} + +typedef struct __XUDCCodeRegion { + unsigned long start,end; +} _XUDCCodeRegion ; + +int +_XUDCGetUDCCPArea(locale,codeset,charset_str,cr,num_cr) +char *locale; +int codeset; +char *charset_str; +_XUDCCodeRegion **cr; +int *num_cr; +{ + int i,num_gr,ret; + _XUDCGlyphRegion *gr; + _XUDCCodeRegion *crr; + + _xudc_utyerror = 0; + _xudc_utyderror = 0; + + if(cr == NULL){ + _xudc_utyerror = 5; + _xudc_utyderror = 1; + _xudc_utyerrno = 0x04 ; + _xudc_utyerrno |= (0x0a<<8) ; + return(_XUDC_ERROR); + } + if(num_cr == NULL){ + _xudc_utyerror = 5; + _xudc_utyderror = 2; + _xudc_utyerrno = 0x04 ; + _xudc_utyerrno |= (0x0a<<8) ; + return(_XUDC_ERROR); + } + + ret = _XUDCGetUDCGIArea(locale,codeset,charset_str,&gr,&num_gr); + if(ret == _XUDC_ERROR){ + _xudc_utyerrno &= 0xff ; + _xudc_utyerrno |= (0x0a<<8) ; + return(ret); + } + + crr = (_XUDCCodeRegion *)Xmalloc(num_gr*sizeof(_XUDCCodeRegion)); + if(crr == NULL){ + Xfree(gr); + _xudc_utyerrno = 0x03 ; + _xudc_utyerrno |= (0x0a<<8) ; + return(_XUDC_ERROR); + } + + for(i=0;i<num_gr;i++){ + ret = _xudc_glyph_to_code(locale,charset_str,codeset, + gr[i].start, &(crr[i].start)); + if(ret == _XUDC_ERROR){ + _xudc_utyerrno |= (0x0a<<8) ; + Xfree(gr); + Xfree(crr); + return(ret); + } + ret = _xudc_glyph_to_code(locale,charset_str,codeset, + gr[i].end, &(crr[i].end)); + if(ret == _XUDC_ERROR){ + _xudc_utyerrno |= (0x0a<<8) ; + Xfree(gr); + Xfree(crr); + return(ret); + } + } + Xfree(gr); + *cr = crr; + *num_cr = num_gr; + return(0); +} + +/* + * code_to_glyph() + * + */ +typedef struct __XUDCGIInf { + char *charset_str; + unsigned long glyph_index; +} _XUDCGIInf ; + +/* + * + * + */ +static Bool vgi_to_gi(gi,vgi,scope) +unsigned long *gi,vgi; +FontScope scope; +{ + if(vgi >= scope->start && vgi <= scope->end){ + if(scope->shift_direction == (unsigned long)'+'){ + *gi = vgi + scope->shift; + } else { + *gi = vgi - scope->shift; + } + return(True); + } + return(False); +} +/* + * + * + */ +static Bool +_xudc_vgi_to_gi(lcd,locale,vglyph,glyph,charset,charsetname,size) +XLCd lcd; +char *locale; +unsigned long vglyph; +unsigned long *glyph; +XlcCharSet charset; +char *charsetname; +int size; +{ + int num = 0,count,num_ret=0; + int i,j,k; + char **value,buf[128],ptr; + FontData font_data; + CodeSet cs; + + + for(i=0;;i++){ + sprintf(buf, "fs%d.charset.name",i); + _XlcGetLocaleDataBase(lcd, "XLC_FONTSET", buf, &value, &count); + if(count > 0){ + if(!_XlcNCompareISOLatin1(charset->name,value[0], + strlen(charset->name))){ + break; + } + } else { + _xudc_utyerrno = 0x17 ; + return(False); + } + } +/* + sprintf(buf, "fs%d.charset.name", codeset-1); + _XlcGetLocaleDataBase(lcd, "XLC_FONTSET", buf, &value, &count); + if(count > 0){ + strcpy(charsetname,value[0]); + } +*/ + sprintf(buf, "fs%d.font.primary", i); + _XlcGetLocaleDataBase(lcd, "XLC_FONTSET", buf, &value, &count); + if(count > 0){ + font_data = read_EncodingInfo(count,value); + for(i=0;i<count;i++){ + for(k=0;k<font_data[i].scopes_num;k++){ + if( vgi_to_gi(glyph,vglyph,&(font_data[i].scopes[k])) == True){ + if (strlen(font_data[i].name) >= size) + return(False); + strcpy(charsetname,font_data[i].name); + return(True); + } + } + } + } + *glyph = vglyph; + return(True); +} +int +_xudc_code_to_glyph(locale,codepoint,gi,num_gi) +char *locale; +unsigned long codepoint; +_XUDCGIInf **gi; +int *num_gi; +{ + XLCd lcd; + unsigned char *from; int from_left; + unsigned char *to ; int to_left = 10; + unsigned char *dst; + unsigned char byte; + unsigned int from32[25]; + unsigned int to32[25]; + int i,j; + char tmp[256],charsetname[256],src[10]; + XlcConv conv; + XlcCharSet charset; + XPointer args[2]; + unsigned long glyph,vglyph; + + from = (unsigned char *)from32; + to = (unsigned char *)to32; + dst = (unsigned char *)to32; + memset(dst,0,25); + + lcd = (XLCd)_XlcGenericLoader(locale); + + for(i=0,j=0;i<4;i++){ + byte = getbyte(codepoint,i); + if(byte){ + src[j] = byte; + j ++; + } + } + src[j] = 0; + sprintf((char *)from,"%s\0",src); + /* multi byte -> vgi */ + conv = _XlcOpenConverter(lcd, XlcNMultiByte, lcd, XlcNCharSet); + from_left = strlen((char *)from); + args[0] = (XPointer) &charset; + _XlcConvert(conv,(XPointer *)&from,&from_left, + (XPointer *)&to, &to_left,args,1); + + /* vgi -> gi */ + vglyph = 0; + for(i=0;dst[i];i++){ + vglyph = ((vglyph << 8) | dst[i]) ; + } + if(_xudc_vgi_to_gi(lcd,locale,vglyph,&glyph,charset,charsetname, + sizeof(charsetname))==False){ + _XlcCloseConverter(conv); + _XlcDestroyLC(lcd); + *num_gi = 0; + return(0); + } + + _XlcCloseConverter(conv); + _XlcDestroyLC(lcd); + + *gi = (_XUDCGIInf *)Xmalloc(sizeof(_XUDCGIInf)); + (*gi)->charset_str = (char *)Xmalloc(strlen(charsetname)+1); + strcpy((*gi)->charset_str,charsetname); + (*gi)->glyph_index = glyph; + if(*gi == NULL){ + _xudc_utyerrno = 0x03 ; + return(_XUDC_ERROR); + } + *num_gi = 1; + return(0); +} + diff --git a/src/util/makekeys.c b/src/util/makekeys.c new file mode 100644 index 00000000..24272bfb --- /dev/null +++ b/src/util/makekeys.c @@ -0,0 +1,259 @@ +/* $Xorg: makekeys.c,v 1.5 2001/02/09 02:03:40 xorgcvs Exp $ */ +/* + +Copyright 1990, 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. + +*/ + +/* Constructs hash tables for XStringToKeysym and XKeysymToString. */ + +#include <X11/X.h> +#include <X11/Xos.h> +#include <X11/keysymdef.h> +#include <stdio.h> + +#ifndef X_NOT_STDC_ENV +#include <stdlib.h> +#else +char *malloc(); +#endif +#if defined(macII) && !defined(__STDC__) /* stdlib.h fails to define these */ +char *malloc(); +#endif /* macII */ + +typedef unsigned long Signature; + +#define KTNUM 3000 + +static struct info { + char *name; + KeySym val; +} info[KTNUM]; + +#define MIN_REHASH 10 +#define MATCHES 10 + +char tab[KTNUM]; +unsigned short offsets[KTNUM]; +unsigned short indexes[KTNUM]; +KeySym values[KTNUM]; +char buf[1024]; + +main() +{ + int ksnum; + int max_rehash; + Signature sig; + register int i, j, k, z; + register char *name; + register char c; + int first; + int best_max_rehash; + int best_z = 0; + int num_found; + KeySym val; + + for (ksnum = 0; 1; (void)fgets(buf, sizeof(buf), stdin)) { + i = scanf("#define XK_%s 0x%lx", buf, &info[ksnum].val); + if (i == EOF) + break; + if (i != 2) + continue; + if (info[ksnum].val == XK_VoidSymbol) + info[ksnum].val = 0; + if (info[ksnum].val > 0xffff) { + fprintf(stderr, + "ignoring illegal keysym (%s), remove it from .h file!\n", + buf); + continue; + } + name = malloc((unsigned)strlen(buf)+1); + if (!name) { + fprintf(stderr, "makekeys: out of memory!\n"); + exit(1); + } + (void)strcpy(name, buf); + info[ksnum].name = name; + ksnum++; + if (ksnum == KTNUM) { + fprintf(stderr, "makekeys: too many keysyms!\n"); + exit(1); + } + } + + printf("/* This file is generated from keysymdef.h. */\n"); + printf("/* Do not edit. */\n"); + printf("\n"); + + best_max_rehash = ksnum; + num_found = 0; + for (z = ksnum; z < KTNUM; z++) { + max_rehash = 0; + for (name = tab, i = z; --i >= 0;) + *name++ = 0; + for (i = 0; i < ksnum; i++) { + name = info[i].name; + sig = 0; + while ((c = *name++)) + sig = (sig << 1) + c; + first = j = sig % z; + for (k = 0; tab[j]; k++) { + j += first + 1; + if (j >= z) + j -= z; + if (j == first) + goto next1; + } + tab[j] = 1; + if (k > max_rehash) + max_rehash = k; + } + if (max_rehash < MIN_REHASH) { + if (max_rehash < best_max_rehash) { + best_max_rehash = max_rehash; + best_z = z; + } + num_found++; + if (num_found >= MATCHES) + break; + } +next1: ; + } + + z = best_z; + printf("#ifdef NEEDKTABLE\n"); + printf("Const unsigned char _XkeyTable[] = {\n"); + printf("0,\n"); + k = 1; + for (i = 0; i < ksnum; i++) { + name = info[i].name; + sig = 0; + while ((c = *name++)) + sig = (sig << 1) + c; + first = j = sig % z; + while (offsets[j]) { + j += first + 1; + if (j >= z) + j -= z; + } + offsets[j] = k; + indexes[i] = k; + val = info[i].val; + printf("0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, ", + (sig >> 8) & 0xff, sig & 0xff, + (val >> 8) & 0xff, val & 0xff); + for (name = info[i].name, k += 5; (c = *name++); k++) + printf("'%c',", c); + printf((i == (ksnum-1)) ? "0\n" : "0,\n"); + } + printf("};\n"); + printf("\n"); + printf("#define KTABLESIZE %d\n", z); + printf("#define KMAXHASH %d\n", best_max_rehash + 1); + printf("\n"); + printf("static Const unsigned short hashString[KTABLESIZE] = {\n"); + for (i = 0; i < z;) { + printf("0x%.4x", offsets[i]); + i++; + if (i == z) + break; + printf((i & 7) ? ", " : ",\n"); + } + printf("\n"); + printf("};\n"); + printf("#endif /* NEEDKTABLE */\n"); + + best_max_rehash = ksnum; + num_found = 0; + for (z = ksnum; z < KTNUM; z++) { + max_rehash = 0; + for (name = tab, i = z; --i >= 0;) + *name++ = 0; + for (i = 0; i < ksnum; i++) { + val = info[i].val; + first = j = val % z; + for (k = 0; tab[j]; k++) { + if (values[j] == val) + goto skip1; + j += first + 1; + if (j >= z) + j -= z; + if (j == first) + goto next2; + } + tab[j] = 1; + values[j] = val; + if (k > max_rehash) + max_rehash = k; +skip1: ; + } + if (max_rehash < MIN_REHASH) { + if (max_rehash < best_max_rehash) { + best_max_rehash = max_rehash; + best_z = z; + } + num_found++; + if (num_found >= MATCHES) + break; + } +next2: ; + } + + z = best_z; + for (i = z; --i >= 0;) + offsets[i] = 0; + for (i = 0; i < ksnum; i++) { + val = info[i].val; + first = j = val % z; + while (offsets[j]) { + if (values[j] == val) + goto skip2; + j += first + 1; + if (j >= z) + j -= z; + } + offsets[j] = indexes[i] + 2; + values[j] = val; +skip2: ; + } + printf("\n"); + printf("#ifdef NEEDVTABLE\n"); + printf("#define VTABLESIZE %d\n", z); + printf("#define VMAXHASH %d\n", best_max_rehash + 1); + printf("\n"); + printf("static Const unsigned short hashKeysym[VTABLESIZE] = {\n"); + for (i = 0; i < z;) { + printf("0x%.4x", offsets[i]); + i++; + if (i == z) + break; + printf((i & 7) ? ", " : ",\n"); + } + printf("\n"); + printf("};\n"); + printf("#endif /* NEEDVTABLE */\n"); + + exit(0); +} diff --git a/src/util/mkks.sh b/src/util/mkks.sh new file mode 100644 index 00000000..262cc954 --- /dev/null +++ b/src/util/mkks.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +cat $* | awk 'BEGIN { \ + printf "/*\n * This file is generated from %s. Do not edit.\n */\n", \ + "$(INCLUDESRC)/keysymdef.h";\ +} \ +/^#define/ { \ + len = length($2)-3; \ + printf("{ \"%s\", %s },\n", substr($2,4,len), $3); \ +}' + diff --git a/src/xcms/AddDIC.c b/src/xcms/AddDIC.c new file mode 100644 index 00000000..aefae0f8 --- /dev/null +++ b/src/xcms/AddDIC.c @@ -0,0 +1,156 @@ +/* $Xorg: AddDIC.c,v 1.3 2000/08/17 19:44:29 cpqbld Exp $ */ + +/* + * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. + * All Rights Reserved + * + * This file is a component of an X Window System-specific implementation + * of Xcms based on the TekColor Color Management System. Permission is + * hereby granted to use, copy, modify, sell, and otherwise distribute this + * software and its documentation for any purpose and without fee, provided + * that this copyright, permission, and disclaimer notice is reproduced in + * all copies of this software and in supporting documentation. TekColor + * is a trademark of Tektronix, Inc. + * + * Tektronix makes no representation about the suitability of this software + * for any purpose. It is provided "as is" and with all faults. + * + * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, + * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX 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 THE PERFORMANCE OF THIS SOFTWARE. + * + * + * NAME + * XcmsAddDIC.c + * + * DESCRIPTION + * Source for XcmsAddColorSpace + * + * + */ + +#include "Xlibint.h" +#include "Xcmsint.h" + + +/* + * DEFINES + */ +#define NextUnregDiCsID(lastid) \ + (XCMS_UNREG_ID(lastid) ? ++lastid : XCMS_FIRST_UNREG_DI_ID) +#define MAX(x,y) ((x) < (y) ? (y) : (x)) + + +/* + * EXTERNS + */ +extern XcmsPerDpyInfo *_XcmsFindDpyInfo(); +extern XPointer *_XcmsPushPointerArray(); +extern XcmsColorFormat _XcmsRegFormatOfPrefix(); +extern XcmsColorSpace **_XcmsDIColorSpaces; +extern XcmsColorSpace *_XcmsDIColorSpacesInit[]; + +/* + * NAME + * XcmsAddColorSpace - Add a Device-Independent Color Space + * + * SYNOPSIS + */ +Status +XcmsAddColorSpace(pCS) + XcmsColorSpace *pCS; +/* + * DESCRIPTION + * DI Color Spaces are managed on a global basis. + * This means that with exception of the provided DI color spaces: + * CIEXYZ, CIExyY, CIELab, CIEuvY, CIELuv, and TekHVC + * DI color spaces may have different XcmsColorFormat IDs between + * clients. So, you must be careful when using XcmsColor + * structures between clients! Use the routines XcmsFormatOfPrefix() + * and XcmsPrefixOfFormat() appropriately. + * + * RETURNS + * XcmsSuccess if succeeded, otherwise XcmsFailure + */ +{ + XcmsColorSpace **papColorSpaces; + XcmsColorSpace *ptmpCS; + XcmsColorFormat lastID = 0; + + if ((pCS->id = _XcmsRegFormatOfPrefix(pCS->prefix)) != 0) { + if (XCMS_DD_ID(pCS->id)) { + /* This is a Device-Dependent Color Space */ + return(XcmsFailure); + } + /* + * REGISTERED DI Color Space + * then see if the color space has already been added to the + * system: + * a. If the same ID/prefix and same XcmsColorSpec is found, + * then its a duplicate, so return success. + * b. If same ID/prefix but different XcmsColorSpec is + * found, then add the color space to the front of the + * list using the same ID. This allows one to override + * an existing DI Color Space. + * c. Otherwise none found so just add the color space. + */ + if ((papColorSpaces = _XcmsDIColorSpaces) != NULL) { + while ((ptmpCS = *papColorSpaces++) != NULL) { + if (pCS->id == ptmpCS->id) { + if (pCS == ptmpCS) { + /* a. duplicate*/ + return(XcmsSuccess); + } + /* b. same ID/prefix but different XcmsColorSpace */ + break; + } + } + } + /* c. None found */ + } else { + /* + * UNREGISTERED DI Color Space + * then see if the color space has already been added to the + * system: + * a. If same prefix and XcmsColorSpec, then + * its a duplicate ... return success. + * b. If same prefix but different XcmsColorSpec, then + * add the color space to the front of the list using + * the same ID. This allows one to override an existing + * DI Color Space. + * c. Otherwise none found so, add the color space using the + * next unregistered ID for the connection. + */ + if ((papColorSpaces = _XcmsDIColorSpaces) != NULL) { + while ((ptmpCS = *papColorSpaces++) != NULL) { + lastID = MAX(lastID, ptmpCS->id); + if (strcmp(pCS->prefix, ptmpCS->prefix) == 0) { + if (pCS == ptmpCS) { + /* a. duplicate */ + return(XcmsSuccess); + } + /* b. same prefix but different XcmsColorSpec */ + pCS->id = ptmpCS->id; + goto AddColorSpace; + } + } + } + /* c. None found */ + pCS->id = NextUnregDiCsID(lastID); + } + + +AddColorSpace: + if ((papColorSpaces = (XcmsColorSpace **) + _XcmsPushPointerArray((XPointer *)_XcmsDIColorSpaces, + (XPointer)pCS, + (XPointer *)_XcmsDIColorSpacesInit)) == NULL) { + return(XcmsFailure); + } + _XcmsDIColorSpaces = papColorSpaces; + return(XcmsSuccess); +} diff --git a/src/xcms/AddSF.c b/src/xcms/AddSF.c new file mode 100644 index 00000000..5c2ae54d --- /dev/null +++ b/src/xcms/AddSF.c @@ -0,0 +1,155 @@ +/* $Xorg: AddSF.c,v 1.3 2000/08/17 19:44:29 cpqbld Exp $ */ + +/* + * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. + * All Rights Reserved + * + * This file is a component of an X Window System-specific implementation + * of Xcms based on the TekColor Color Management System. Permission is + * hereby granted to use, copy, modify, sell, and otherwise distribute this + * software and its documentation for any purpose and without fee, provided + * that this copyright, permission, and disclaimer notice is reproduced in + * all copies of this software and in supporting documentation. TekColor + * is a trademark of Tektronix, Inc. + * + * Tektronix makes no representation about the suitability of this software + * for any purpose. It is provided "as is" and with all faults. + * + * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, + * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX 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 THE PERFORMANCE OF THIS SOFTWARE. + * + * + * NAME + * XcmsAddSF.c + * + * DESCRIPTION + * Source for XcmsAddFunctionSet + * + * + */ + +#include "Xlibint.h" +#include "Xcmsint.h" + +/* + * DEFINES + */ +#define NextUnregDdCsID(lastid) \ + (XCMS_UNREG_ID(lastid) ? ++lastid : XCMS_FIRST_UNREG_DD_ID) +#define MIN(x,y) ((x) > (y) ? (y) : (x)) + + +/* + * EXTERNS + */ +extern XPointer *_XcmsPushPointerArray(); +extern XcmsColorFormat _XcmsRegFormatOfPrefix(); +extern XcmsFunctionSet **_XcmsSCCFuncSets; +extern XcmsFunctionSet **_XcmsSCCFuncSetsInit; +extern XcmsColorSpace **_XcmsDDColorSpaces; +extern XcmsColorSpace **_XcmsDDColorSpacesInit; + + + +/* + * NAME + * XcmsAddFunctionSet - Add an Screen Color Characterization + * Function Set + * + * SYNOPSIS + */ +Status +XcmsAddFunctionSet(pNewFS) + XcmsFunctionSet *pNewFS; +/* + * DESCRIPTION + * Additional Screen Color Characterization Function Sets are + * managed on a global basis. This means that with exception + * of the provided DD color spaces: + * RGB and RGBi + * DD color spaces may have different XcmsColorFormat IDs between + * clients. So, you must be careful when using XcmsColorFormat + * across clients! Use the routines XcmsFormatOfPrefix() + * and XcmsPrefixOfFormat() appropriately. + * + * RETURNS + * XcmsSuccess if succeeded, otherwise XcmsFailure + * + * CAVEATS + * Additional Screen Color Characterization Function Sets + * should be added prior to any use of the routine + * XcmsCreateCCC(). If not, XcmsCCC structures created + * prior to the call of this routines will not have had + * a chance to initialize using the added Screen Color + * Characterization Function Set. + */ +{ + XcmsFunctionSet **papSCCFuncSets = _XcmsSCCFuncSets; + XcmsColorSpace **papNewCSs; + XcmsColorSpace *pNewCS, **paptmpCS; + XcmsColorFormat lastID = 0; + + + if (papSCCFuncSets != NULL) { + if ((papNewCSs = pNewFS->DDColorSpaces) == NULL) { + /* + * Error, new Screen Color Characterization Function Set + * missing color spaces + */ + return(XcmsFailure); + } + while ((pNewCS = *papNewCSs++) != NULL) { + if ((pNewCS->id = _XcmsRegFormatOfPrefix(pNewCS->prefix)) != 0) { + if (XCMS_DI_ID(pNewCS->id)) { + /* This is a Device-Independent Color Space */ + return(XcmsFailure); + } + /* + * REGISTERED DD Color Space + * therefore use the registered ID. + */ + } else { + /* + * UNREGISTERED DD Color Space + * then see if the color space is already in + * _XcmsDDColorSpaces. + * a. If same prefix, then use the same ID. + * b. Otherwise, use a new ID. + */ + for (paptmpCS = _XcmsDDColorSpaces; *paptmpCS != NULL; + paptmpCS++){ + lastID = MIN(lastID, (*paptmpCS)->id); + if (strcmp(pNewCS->prefix, (*paptmpCS)->prefix) == 0) { + pNewCS->id = (*paptmpCS)->id; + break; + } + } + if (pNewCS->id == 0) { + /* still haven't found one */ + pNewCS->id = NextUnregDdCsID(lastID); + if ((paptmpCS = (XcmsColorSpace **)_XcmsPushPointerArray( + (XPointer *) _XcmsDDColorSpaces, + (XPointer) pNewCS, + (XPointer *) _XcmsDDColorSpacesInit)) == NULL) { + return(XcmsFailure); + } + _XcmsDDColorSpaces = paptmpCS; + } + } + } + } + if ((papSCCFuncSets = (XcmsFunctionSet **) + _XcmsPushPointerArray((XPointer *) _XcmsSCCFuncSets, + (XPointer) pNewFS, + (XPointer *)_XcmsSCCFuncSetsInit)) == NULL) { + return(XcmsFailure); + } + _XcmsSCCFuncSets = papSCCFuncSets; + + return(XcmsSuccess); +} diff --git a/src/xcms/CCC.c b/src/xcms/CCC.c new file mode 100644 index 00000000..9a7d5162 --- /dev/null +++ b/src/xcms/CCC.c @@ -0,0 +1,287 @@ +/* $Xorg: CCC.c,v 1.4 2001/02/09 02:03:31 xorgcvs Exp $ */ + +/* + * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. + * All Rights Reserved + * + * This file is a component of an X Window System-specific implementation + * of Xcms based on the TekColor Color Management System. Permission is + * hereby granted to use, copy, modify, sell, and otherwise distribute this + * software and its documentation for any purpose and without fee, provided + * that this copyright, permission, and disclaimer notice is reproduced in + * all copies of this software and in supporting documentation. TekColor + * is a trademark of Tektronix, Inc. + * + * Tektronix makes no representation about the suitability of this software + * for any purpose. It is provided "as is" and with all faults. + * + * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, + * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX 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 THE PERFORMANCE OF THIS SOFTWARE. + * + * + * NAME + * XcmsCCC.c - Color Conversion Context Routines + * + * DESCRIPTION + * Routines to create, access, and free Color Conversion + * Context structures. + * + * + */ + +/* + +Copyright 1994, 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. + +*/ + +#include <stdio.h> +#include "Xlibint.h" +#include "Xcmsint.h" + +extern XcmsIntensityMap *_XcmsGetIntensityMap(); + + + +/************************************************************************ + * * + * PUBLIC INTERFACES * + * * + ************************************************************************/ + +/* + * NAME + * XcmsCreateCCC + * + * SYNOPSIS + */ + +XcmsCCC +XcmsCreateCCC(dpy, screenNumber, visual, clientWhitePt, gamutCompProc, + gamutCompClientData, whitePtAdjProc, whitePtAdjClientData) + Display *dpy; + int screenNumber; + Visual *visual; + XcmsColor *clientWhitePt; + XcmsCompressionProc gamutCompProc; + XPointer gamutCompClientData; + XcmsWhiteAdjustProc whitePtAdjProc; + XPointer whitePtAdjClientData; +/* + * DESCRIPTION + * Given a Display, Screen, Visual, etc., this routine creates + * an appropriate Color Conversion Context. + * + * RETURNS + * Returns NULL if failed; otherwise address of the newly + * created XcmsCCC. + * + */ +{ + XcmsCCC pDefaultCCC = XcmsDefaultCCC(dpy, screenNumber); + XcmsCCC newccc; + XcmsIntensityMap *pIMap; + XcmsPerScrnInfo *pNewScrnInfo; + + if (pDefaultCCC == NULL || + !(newccc = (XcmsCCC) Xcalloc(1, (unsigned) sizeof(XcmsCCCRec)))) { + return(NULL); + } + + /* + * Should inherit the following as result of a memmove(): + * dpy + * screenNumber + * pPerScrnInfo + */ + memcpy((char *)newccc, (char *)pDefaultCCC, sizeof(XcmsCCCRec)); + if (clientWhitePt) { + memcpy((char *)&newccc->clientWhitePt, (char *)clientWhitePt, + sizeof(XcmsColor)); + } + if (gamutCompProc) { + newccc->gamutCompProc = gamutCompProc; + } + if (gamutCompClientData) { + newccc->gamutCompClientData = gamutCompClientData; + } + if (whitePtAdjProc) { + newccc->whitePtAdjProc = whitePtAdjProc; + } + if (whitePtAdjClientData) { + newccc->whitePtAdjClientData = whitePtAdjClientData; + } + + /* + * Now check our list of per-Visual Intensity tables. + * If one exists replace the pPerScrnInfo. + */ + if ((pIMap = _XcmsGetIntensityMap(dpy, visual)) != NULL) { + if (!(pNewScrnInfo = (XcmsPerScrnInfo *) + Xcalloc(1, (unsigned) sizeof(XcmsPerScrnInfo)))) { + Xfree(newccc); + return(NULL); + } + memcpy((char *)pNewScrnInfo, (char *)newccc->pPerScrnInfo, + sizeof(XcmsPerScrnInfo)); + pNewScrnInfo->screenData = pIMap->screenData; + newccc->pPerScrnInfo = pNewScrnInfo; + } + + /* + * Set visual component + */ + newccc->visual = visual; + + return(newccc); +} + + +/* + * NAME + * XcmsDefaultCCC + * + * SYNOPSIS + */ +XcmsCCC +XcmsDefaultCCC(dpy, screenNumber) + Display *dpy; + int screenNumber; +/* + * DESCRIPTION + * Given a Display and Screen, this routine creates + * returns the Screen's default Color Conversion Context. + * Note that a Screen's default CCC is built with the + * screen default visual. + * + * RETURNS + * Returns NULL if failed; otherwise address of the + * XcmsCCC for the Screen's default CCC. + * + */ +{ + XcmsCCC ccc; + + + if ((screenNumber < 0) || (screenNumber >= ScreenCount(dpy))) { + return((XcmsCCC)NULL); + } + + /* + * Check if the XcmsCCC's for each screen has been created + */ + if ((XcmsCCC)dpy->cms.defaultCCCs == NULL) { + if (!_XcmsInitDefaultCCCs(dpy)) { + return((XcmsCCC)NULL); + } + } + + ccc = (XcmsCCC)dpy->cms.defaultCCCs + screenNumber; + + if (!ccc->pPerScrnInfo) { + /* + * Need to create the XcmsPerScrnInfo structure. The + * _XcmsInitScrnInfo routine will create the XcmsPerScrnInfo + * structure as well as initialize its functionSet and pScreenData + * components. + */ + if (!_XcmsInitScrnInfo(dpy, screenNumber)) { + return((XcmsCCC)NULL); + } + return(ccc); + } else { + /* + * If ccc->pPerScrnInfo->state == XcmsInitSuccess, + * then the pPerScrnInfo component has already been initialized + * therefore, just return ccc. + * If ccc->pPerScrnInfo->state == XcmsInitFailure, + * then this means that we already attempted to initialize + * the pPerScrnInfo component but failed therefore stuffing + * the pPerScrnInfo component with defaults. Just return ccc. + * If ccc->pPerScrnInfo->state == XcmsInitNone, + * then attempt to initialize the pPerScrnInfo component. + */ + switch (ccc->pPerScrnInfo->state) { + case XcmsInitFailure : + /* fall through */ + case XcmsInitSuccess : + return(ccc); + case XcmsInitNone : + /* XcmsPerScreenInfo has not been initialized */ + if (!_XcmsInitScrnInfo(dpy, screenNumber)) { + return((XcmsCCC)NULL); + } + return(ccc); + default : + return((XcmsCCC)NULL); + } + } +} + + +/* + * NAME + * XcmsFreeCCC + * + * SYNOPSIS + */ +void +XcmsFreeCCC(ccc) + XcmsCCC ccc; +/* + * DESCRIPTION + * Frees memory associated with a Color Conversion Context + * that was created with XcmsCreateCCC(). + * + * RETURNS + * void + * + */ +{ + if (ccc->dpy->cms.defaultCCCs && + ccc == ((XcmsCCC)ccc->dpy->cms.defaultCCCs) + ccc->screenNumber) { + /* do not allow clients to free DefaultCCC's */ + return; + } + + /* + * Note that XcmsPerScrnInfo sub-structures are freed here only if + * they are for visuals that have per-Visual intensity tables. + * Otherwise the XcmsPerScrnInfo structure is being shared! + * For the latter, there is only one allocated per Screen and it just + * so happens * that we place its initial reference is placed in the + * default CCC. The routine _XcmsFreeDefaultCCCs frees them. + */ + if (_XcmsGetIntensityMap(ccc->dpy, ccc->visual) != NULL) { + Xfree(ccc->pPerScrnInfo); + } + + Xfree(ccc); +} diff --git a/src/xcms/CvColW.c b/src/xcms/CvColW.c new file mode 100644 index 00000000..249e30e5 --- /dev/null +++ b/src/xcms/CvColW.c @@ -0,0 +1,139 @@ +/* $Xorg: CvColW.c,v 1.3 2000/08/17 19:44:32 cpqbld Exp $ */ + +/* + * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. + * All Rights Reserved + * + * This file is a component of an X Window System-specific implementation + * of Xcms based on the TekColor Color Management System. Permission is + * hereby granted to use, copy, modify, sell, and otherwise distribute this + * software and its documentation for any purpose and without fee, provided + * that this copyright, permission, and disclaimer notice is reproduced in + * all copies of this software and in supporting documentation. TekColor + * is a trademark of Tektronix, Inc. + * + * Tektronix makes no representation about the suitability of this software + * for any purpose. It is provided "as is" and with all faults. + * + * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, + * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX 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 THE PERFORMANCE OF THIS SOFTWARE. + * + * + * + * NAME + * XcmsCvColW.c + * + * DESCRIPTION + * <overall description of what the package does> + * + * + */ + +#include "Xlibint.h" +#include "Xcmsint.h" + + +/************************************************************************ + * * + * API PRIVATE ROUTINES * + * * + ************************************************************************/ + + +/* + * NAME + * _XcmsConvertColorsWithWhitePt - Convert XcmsColor structures + * + * SYNOPSIS + */ +Status +_XcmsConvertColorsWithWhitePt(ccc, pColors_in_out, pWhitePt, nColors, + newFormat, pCompressed) + XcmsCCC ccc; + XcmsColor *pColors_in_out; + XcmsColor *pWhitePt; + unsigned int nColors; + XcmsColorFormat newFormat; + Bool *pCompressed; +/* + * DESCRIPTION + * Convert XcmsColor structures between device-independent + * and/or device-dependent formats but allowing the calling + * routine to specify the white point to be associated + * with the color specifications (overriding + * ccc->clientWhitePt). + * + * This routine has been provided for use in white point + * adjustment routines. + * + * RETURNS + * XcmsFailure if failed, + * XcmsSuccess if succeeded without gamut compression, + * XcmsSuccessWithCompression if succeeded with gamut + * compression. + * + */ +{ + if (ccc == NULL || pColors_in_out == NULL || + pColors_in_out->format == XcmsUndefinedFormat) { + return(XcmsFailure); + } + + if (nColors == 0 || pColors_in_out->format == newFormat) { + /* do nothing */ + return(XcmsSuccess); + } + + if (XCMS_DI_ID(pColors_in_out->format) && XCMS_DI_ID(newFormat)) { + /* + * Device-Independent to Device-Independent Conversion + */ + return(_XcmsDIConvertColors(ccc, pColors_in_out, pWhitePt, nColors, + newFormat)); + } + if (XCMS_DD_ID(pColors_in_out->format) && XCMS_DD_ID(newFormat)) { + /* + * Device-Dependent to Device-Dependent Conversion + */ + return(_XcmsDDConvertColors(ccc, pColors_in_out, nColors, newFormat, + pCompressed)); + } + + /* + * Otherwise we have: + * 1. Device-Independent to Device-Dependent Conversion + * OR + * 2. Device-Dependent to Device-Independent Conversion + */ + + if (XCMS_DI_ID(pColors_in_out->format)) { + /* + * 1. Device-Independent to Device-Dependent Conversion + */ + /* First convert to CIEXYZ */ + if (_XcmsDIConvertColors(ccc, pColors_in_out, pWhitePt, nColors, + XcmsCIEXYZFormat) == XcmsFailure) { + return(XcmsFailure); + } + /* Then convert to DD Format */ + return(_XcmsDDConvertColors(ccc, pColors_in_out, nColors, newFormat, + pCompressed)); + } else { + /* + * 2. Device-Dependent to Device-Independent Conversion + */ + /* First convert to CIEXYZ */ + if (_XcmsDDConvertColors(ccc, pColors_in_out, nColors, + XcmsCIEXYZFormat, pCompressed) == XcmsFailure) { + return(XcmsFailure); + } + /* Then convert to DI Format */ + return(_XcmsDIConvertColors(ccc, pColors_in_out, pWhitePt, nColors, + newFormat)); + } +} diff --git a/src/xcms/CvCols.c b/src/xcms/CvCols.c new file mode 100644 index 00000000..d74ea323 --- /dev/null +++ b/src/xcms/CvCols.c @@ -0,0 +1,1048 @@ +/* $Xorg: CvCols.c,v 1.3 2000/08/17 19:44:32 cpqbld Exp $ */ + +/* + * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. + * All Rights Reserved + * + * This file is a component of an X Window System-specific implementation + * of Xcms based on the TekColor Color Management System. Permission is + * hereby granted to use, copy, modify, sell, and otherwise distribute this + * software and its documentation for any purpose and without fee, provided + * that this copyright, permission, and disclaimer notice is reproduced in + * all copies of this software and in supporting documentation. TekColor + * is a trademark of Tektronix, Inc. + * + * Tektronix makes no representation about the suitability of this software + * for any purpose. It is provided "as is" and with all faults. + * + * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, + * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX 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 THE PERFORMANCE OF THIS SOFTWARE. + * + * + * NAME + * XcmsCvCols.c + * + * DESCRIPTION + * Xcms API routine that converts between the + * device-independent color spaces. + * + * + */ + +#include "Xlibint.h" +#include "Xcmsint.h" + +/* + * EXTERNS + * External declarations required locally to this package + * that are not already declared in any of the included header + * files (external includes or internal includes). + */ +extern XcmsRegColorSpaceEntry _XcmsRegColorSpaces[]; +extern XcmsColorSpace **_XcmsDIColorSpaces; +extern XcmsColorSpace **_XcmsDDColorSpaces; + +/* + * LOCAL DEFINES + */ +#define DD_FORMAT 0x01 +#define DI_FORMAT 0x02 +#define MIX_FORMAT 0x04 +#ifndef MAX +# define MAX(x,y) ((x) > (y) ? (x) : (y)) +#endif + +/* + * FORWARD DECLARATIONS + */ +Status _XcmsDIConvertColors(); +Status _XcmsDDConvertColors(); + + +/************************************************************************ + * * + * PRIVATE ROUTINES * + * * + ************************************************************************/ + +/* + * NAME + * EqualCIEXYZ + * + * SYNOPSIS + */ +static int +EqualCIEXYZ(p1, p2) + XcmsColor *p1, *p2; +/* + * DESCRIPTION + * Compares two XcmsColor structures that are in XcmsCIEXYZFormat + * + * RETURNS + * Returns 1 if equal; 0 otherwise. + * + */ +{ + if (p1->format != XcmsCIEXYZFormat || p2->format != XcmsCIEXYZFormat) { + return(0); + } + if ((p1->spec.CIEXYZ.X != p2->spec.CIEXYZ.X) + || (p1->spec.CIEXYZ.Y != p2->spec.CIEXYZ.Y) + || (p1->spec.CIEXYZ.Z != p2->spec.CIEXYZ.Z)) { + return(0); + } + return(1); +} + + +/* + * NAME + * XcmsColorSpace + * + * SYNOPSIS + */ +static XcmsColorSpace * +ColorSpaceOfID(ccc, id) + XcmsCCC ccc; + XcmsColorFormat id; +/* + * DESCRIPTION + * Returns a pointer to the color space structure + * (XcmsColorSpace) associated with the specified color space + * ID. + * + * RETURNS + * Pointer to matching XcmsColorSpace structure if found; + * otherwise NULL. + */ +{ + XcmsColorSpace **papColorSpaces; + + if (ccc == NULL) { + return(NULL); + } + + /* + * First try Device-Independent color spaces + */ + papColorSpaces = _XcmsDIColorSpaces; + if (papColorSpaces != NULL) { + while (*papColorSpaces != NULL) { + if ((*papColorSpaces)->id == id) { + return(*papColorSpaces); + } + papColorSpaces++; + } + } + + /* + * Next try Device-Dependent color spaces + */ + papColorSpaces = ((XcmsFunctionSet *)ccc->pPerScrnInfo->functionSet)->DDColorSpaces; + if (papColorSpaces != NULL) { + while (*papColorSpaces != NULL) { + if ((*papColorSpaces)->id == id) { + return(*papColorSpaces); + } + papColorSpaces++; + } + } + + return(NULL); +} + + +/* + * NAME + * ValidDIColorSpaceID + * + * SYNOPSIS + */ +static int +ValidDIColorSpaceID(id) + XcmsColorFormat id; +/* + * DESCRIPTION + * Determines if the specified color space ID is a valid + * Device-Independent color space in the specified Color + * Conversion Context. + * + * RETURNS + * Returns zero if not valid; otherwise non-zero. + */ +{ + XcmsColorSpace **papRec; + papRec = _XcmsDIColorSpaces; + if (papRec != NULL) { + while (*papRec != NULL) { + if ((*papRec)->id == id) { + return(1); + } + papRec++; + } + } + return(0); +} + + +/* + * NAME + * ValidDDColorSpaceID + * + * SYNOPSIS + */ +static int +ValidDDColorSpaceID(ccc, id) + XcmsCCC ccc; + XcmsColorFormat id; +/* + * DESCRIPTION + * Determines if the specified color space ID is a valid + * Device-Dependent color space in the specified Color + * Conversion Context. + * + * RETURNS + * Returns zero if not valid; otherwise non-zero. + */ +{ + XcmsColorSpace **papRec; + + if (ccc->pPerScrnInfo->state != XcmsInitNone) { + papRec = ((XcmsFunctionSet *)ccc->pPerScrnInfo->functionSet)->DDColorSpaces; + while (*papRec != NULL) { + if ((*papRec)->id == id) { + return(1); + } + papRec++; + } + } + return(0); +} + + +/* + * NAME + * ConvertMixedColors - Convert XcmsColor structures + * + * SYNOPSIS + */ +static Status +ConvertMixedColors(ccc, pColors_in_out, pWhitePt, nColors, + targetFormat, format_flag) + XcmsCCC ccc; + XcmsColor *pColors_in_out; + XcmsColor *pWhitePt; + unsigned int nColors; + XcmsColorFormat targetFormat; + unsigned char format_flag; +/* + * DESCRIPTION + * This routine will only convert the following types of + * batches: + * DI to DI + * DD to DD + * DD to CIEXYZ + * In other words, it will not convert the following types of + * batches: + * DI to DD + * DD to DI(not CIEXYZ) + * + * format_flag: + * 0x01 : convert Device-Dependent only specifications to the + * target format. + * 0x02 : convert Device-Independent only specifications to the + * target format. + * 0x03 : convert all specifications to the target format. + * + * RETURNS + * XcmsFailure if failed, + * XcmsSuccess if none of the color specifications were + * compressed in the conversion process + * XcmsSuccessWithCompression if at least one of the + * color specifications were compressed in the + * conversion process. + * + */ +{ + XcmsColor *pColor, *pColors_start; + XcmsColorFormat format; + Status retval_tmp; + Status retval = XcmsSuccess; + unsigned int iColors; + unsigned int nBatch; + + /* + * Convert array of mixed color specifications in batches of + * contiguous formats to the target format + */ + iColors = 0; + while (iColors < nColors) { + /* + * Find contiguous array of color specifications with the + * same format + */ + pColor = pColors_start = pColors_in_out + iColors; + format = pColors_start->format; + nBatch = 0; + while (iColors < nColors && pColor->format == format) { + pColor++; + nBatch++; + iColors++; + } + if (format != targetFormat) { + /* + * Need to convert this batch from current format to target format. + */ + if (XCMS_DI_ID(format) && (format_flag & DI_FORMAT) && + XCMS_DI_ID(targetFormat)) { + /* + * DI->DI + * + * Format of interest is Device-Independent, + * This batch contains Device-Independent specifications, and + * the Target format is Device-Independent. + */ + retval_tmp = _XcmsDIConvertColors(ccc, pColors_start, pWhitePt, + nBatch, targetFormat); + } else if (XCMS_DD_ID(format) && (format_flag & DD_FORMAT) && + (targetFormat == XcmsCIEXYZFormat)) { + /* + * DD->CIEXYZ + * + * Format of interest is Device-Dependent, + * This batch contains Device-Dependent specifications, and + * the Target format is CIEXYZ. + * + * Since DD->CIEXYZ we can use NULL instead of pCompressed. + */ + if ((ccc->whitePtAdjProc != NULL) && !_XcmsEqualWhitePts(ccc, + pWhitePt, ScreenWhitePointOfCCC(ccc))) { + /* + * Need to call WhiteAdjustProc (Screen White Point to + * White Point). + */ + retval_tmp = (*ccc->whitePtAdjProc)(ccc, + ScreenWhitePointOfCCC(ccc), pWhitePt, + XcmsCIEXYZFormat, pColors_start, nBatch, + (Bool *)NULL); + } else { + retval_tmp = _XcmsDDConvertColors(ccc, pColors_start, + nBatch, XcmsCIEXYZFormat, (Bool *)NULL); + } + } else if (XCMS_DD_ID(format) && (format_flag & DD_FORMAT) && + XCMS_DD_ID(targetFormat)) { + /* + * DD->DD(not CIEXYZ) + * + * Format of interest is Device-Dependent, + * This batch contains Device-Dependent specifications, and + * the Target format is Device-Dependent and not CIEXYZ. + */ + retval_tmp = _XcmsDDConvertColors(ccc, pColors_start, nBatch, + targetFormat, (Bool *)NULL); + } else { + /* + * This routine is called for the wrong reason. + */ + return(XcmsFailure); + } + if (retval_tmp == XcmsFailure) { + return(XcmsFailure); + } + retval = MAX(retval, retval_tmp); + } + } + return(retval); +} + + +/************************************************************************ + * * + * API PRIVATE ROUTINES * + * * + ************************************************************************/ + +/* + * NAME + * _XcmsEqualWhitePts + * + * SYNOPSIS + */ +int +_XcmsEqualWhitePts(ccc, pWhitePt1, pWhitePt2) + XcmsCCC ccc; + XcmsColor *pWhitePt1, *pWhitePt2; +/* + * DESCRIPTION + * + * RETURNS + * Returns 0 if not equal; otherwise 1. + * + */ +{ + XcmsColor tmp1, tmp2; + + memcpy((char *)&tmp1, (char *)pWhitePt1, sizeof(XcmsColor)); + memcpy((char *)&tmp2, (char *)pWhitePt2, sizeof(XcmsColor)); + + if (tmp1.format != XcmsCIEXYZFormat) { + if (_XcmsDIConvertColors(ccc, &tmp1, (XcmsColor *) NULL, 1, + XcmsCIEXYZFormat)==0) { + return(0); + } + } + + if (tmp2.format != XcmsCIEXYZFormat) { + if (_XcmsDIConvertColors(ccc, &tmp2, (XcmsColor *) NULL, 1, + XcmsCIEXYZFormat)==0) { + return(0); + } + } + + return (EqualCIEXYZ(&tmp1, &tmp2)); +} + + +/* + * NAME + * _XcmsDIConvertColors - Convert XcmsColor structures + * + * SYNOPSIS + */ +Status +_XcmsDIConvertColors(ccc, pColors_in_out, pWhitePt, nColors, + newFormat) + XcmsCCC ccc; + XcmsColor *pColors_in_out; + XcmsColor *pWhitePt; + unsigned int nColors; + XcmsColorFormat newFormat; +/* + * DESCRIPTION + * Convert XcmsColor structures to another Device-Independent + * form. + * + * Here are some assumptions that this routine makes: + * 1. The calling routine has already checked if + * pColors_in_out->format == newFormat, therefore + * there is no need to check again here. + * 2. The calling routine has already checked nColors, + * therefore this routine assumes nColors > 0. + * 3. The calling routine may want to convert only between + * CIExyY <-> CIEXYZ <-> CIEuvY + * therefore, this routine allows pWhitePt to equal NULL. + * + * + * RETURNS + * XcmsFailure if failed, + * XcmsSuccess if succeeded. + * + */ +{ + XcmsColorSpace *pFrom, *pTo; + XcmsConversionProc *src_to_CIEXYZ, *src_from_CIEXYZ; + XcmsConversionProc *dest_to_CIEXYZ, *dest_from_CIEXYZ; + XcmsConversionProc *to_CIEXYZ_stop, *from_CIEXYZ_start; + XcmsConversionProc *tmp; + + /* + * Allow pWhitePt to equal NULL. This appropriate when converting + * anywhere between: + * CIExyY <-> CIEXYZ <-> CIEuvY + */ + + if (pColors_in_out == NULL || + !ValidDIColorSpaceID(pColors_in_out->format) || + !ValidDIColorSpaceID(newFormat)) { + return(XcmsFailure); + } + + /* + * Get a handle on the function list for the current specification format + */ + if ((pFrom = ColorSpaceOfID(ccc, pColors_in_out->format)) + == NULL) { + return(XcmsFailure); + } + + /* + * Get a handle on the function list for the new specification format + */ + if ((pTo = ColorSpaceOfID(ccc, newFormat)) == NULL) { + return(XcmsFailure); + } + + src_to_CIEXYZ = pFrom->to_CIEXYZ; + src_from_CIEXYZ = pFrom->from_CIEXYZ; + dest_to_CIEXYZ = pTo->to_CIEXYZ; + dest_from_CIEXYZ = pTo->from_CIEXYZ; + + if (pTo->inverse_flag && pFrom->inverse_flag) { + /* + * Find common function pointers + */ + for (to_CIEXYZ_stop = src_to_CIEXYZ; *to_CIEXYZ_stop; to_CIEXYZ_stop++){ + for (tmp = dest_to_CIEXYZ; *tmp; tmp++) { + if (*to_CIEXYZ_stop == *tmp) { + goto Continue; + } + } + } + +Continue: + + /* + * Execute the functions to CIEXYZ, stopping short as necessary + */ + while (src_to_CIEXYZ != to_CIEXYZ_stop) { + if ((*src_to_CIEXYZ++)(ccc, pWhitePt, pColors_in_out, + nColors) == XcmsFailure) { + return(XcmsFailure); + } + } + + /* + * Determine where to start on the from_CIEXYZ path. + */ + from_CIEXYZ_start = dest_from_CIEXYZ; + tmp = src_from_CIEXYZ; + while ((*from_CIEXYZ_start == *tmp) && (*from_CIEXYZ_start != NULL)) { + from_CIEXYZ_start++; + tmp++; + } + + } else { + /* + * The function in at least one of the Color Spaces are not + * complementary, i.e., + * for an i, 0 <= i < n elements + * from_CIEXYZ[i] is not the inverse of to_CIEXYZ[i] + * + * Execute the functions all the way to CIEXYZ + */ + while (*src_to_CIEXYZ) { + if ((*src_to_CIEXYZ++)(ccc, pWhitePt, pColors_in_out, + nColors) == XcmsFailure) { + return(XcmsFailure); + } + } + + /* + * Determine where to start on the from_CIEXYZ path. + */ + from_CIEXYZ_start = dest_from_CIEXYZ; + } + + + /* + * Execute the functions from CIEXYZ. + */ + while (*from_CIEXYZ_start) { + if ((*from_CIEXYZ_start++)(ccc, pWhitePt, pColors_in_out, + nColors) == XcmsFailure) { + return(XcmsFailure); + } + } + + return(XcmsSuccess); +} + + +/* + * NAME + * _XcmsDDConvertColors - Convert XcmsColor structures + * + * SYNOPSIS + */ +Status +_XcmsDDConvertColors(ccc, pColors_in_out, nColors, newFormat, + pCompressed) + XcmsCCC ccc; + XcmsColor *pColors_in_out; + unsigned int nColors; + XcmsColorFormat newFormat; + Bool *pCompressed; +/* + * DESCRIPTION + * Convert XcmsColor structures: + * + * 1. From CIEXYZ to Device-Dependent formats (typically RGB and + * RGBi), + * or + * 2. Between Device-Dependent formats (typically RGB and RGBi). + * + * Assumes that these specifications have already been white point + * adjusted if necessary from Client White Point to Screen + * White Point. Therefore, the white point now associated + * with the specifications is the Screen White Point. + * + * pCompressed may be NULL. If so this indicates that the + * calling routine is not interested in knowing exactly which + * color was compressed, if any. + * + * + * RETURNS + * XcmsFailure if failed, + * XcmsSuccess if none of the color specifications were + * compressed in the conversion process + * XcmsSuccessWithCompression if at least one of the + * color specifications were compressed in the + * conversion process. + * + */ +{ + XcmsColorSpace *pFrom, *pTo; + XcmsConversionProc *src_to_CIEXYZ, *src_from_CIEXYZ; + XcmsConversionProc *dest_to_CIEXYZ, *dest_from_CIEXYZ; + XcmsConversionProc *from_CIEXYZ_start, *to_CIEXYZ_stop; + XcmsConversionProc *tmp; + int retval; + int hasCompressed = 0; + + if (ccc == NULL || pColors_in_out == NULL) { + return(XcmsFailure); + } + + if (nColors == 0 || pColors_in_out->format == newFormat) { + /* do nothing */ + return(XcmsSuccess); + } + + if (((XcmsFunctionSet *)ccc->pPerScrnInfo->functionSet) == NULL) { + return(XcmsFailure); /* hmm, an internal error? */ + } + + /* + * Its ok if pColors_in_out->format == XcmsCIEXYZFormat + * or + * if newFormat == XcmsCIEXYZFormat + */ + if ( !( ValidDDColorSpaceID(ccc, pColors_in_out->format) + || + (pColors_in_out->format == XcmsCIEXYZFormat)) + || + !(ValidDDColorSpaceID(ccc, newFormat) + || + newFormat == XcmsCIEXYZFormat)) { + return(XcmsFailure); + } + + if ((pFrom = ColorSpaceOfID(ccc, pColors_in_out->format)) == NULL){ + return(XcmsFailure); + } + + if ((pTo = ColorSpaceOfID(ccc, newFormat)) == NULL) { + return(XcmsFailure); + } + + src_to_CIEXYZ = pFrom->to_CIEXYZ; + src_from_CIEXYZ = pFrom->from_CIEXYZ; + dest_to_CIEXYZ = pTo->to_CIEXYZ; + dest_from_CIEXYZ = pTo->from_CIEXYZ; + + if (pTo->inverse_flag && pFrom->inverse_flag) { + /* + * Find common function pointers + */ + for (to_CIEXYZ_stop = src_to_CIEXYZ; *to_CIEXYZ_stop; to_CIEXYZ_stop++){ + for (tmp = dest_to_CIEXYZ; *tmp; tmp++) { + if (*to_CIEXYZ_stop == *tmp) { + goto Continue; + } + } + } +Continue: + + /* + * Execute the functions + */ + while (src_to_CIEXYZ != to_CIEXYZ_stop) { + retval = (*src_to_CIEXYZ++)(ccc, pColors_in_out, nColors, + pCompressed); + if (retval == XcmsFailure) { + return(XcmsFailure); + } + hasCompressed |= (retval == XcmsSuccessWithCompression); + } + + /* + * Determine where to start on the from_CIEXYZ path. + */ + from_CIEXYZ_start = dest_from_CIEXYZ; + tmp = src_from_CIEXYZ; + while ((*from_CIEXYZ_start == *tmp) && (*from_CIEXYZ_start != NULL)) { + from_CIEXYZ_start++; + tmp++; + } + + } else { + /* + * The function in at least one of the Color Spaces are not + * complementary, i.e., + * for an i, 0 <= i < n elements + * from_CIEXYZ[i] is not the inverse of to_CIEXYZ[i] + * + * Execute the functions all the way to CIEXYZ + */ + while (*src_to_CIEXYZ) { + retval = (*src_to_CIEXYZ++)(ccc, pColors_in_out, nColors, + pCompressed); + if (retval == XcmsFailure) { + return(XcmsFailure); + } + hasCompressed |= (retval == XcmsSuccessWithCompression); + } + + /* + * Determine where to start on the from_CIEXYZ path. + */ + from_CIEXYZ_start = dest_from_CIEXYZ; + } + + while (*from_CIEXYZ_start) { + retval = (*from_CIEXYZ_start++)(ccc, pColors_in_out, nColors, + pCompressed); + if (retval == XcmsFailure) { + return(XcmsFailure); + } + hasCompressed |= (retval == XcmsSuccessWithCompression); + } + + return(hasCompressed ? XcmsSuccessWithCompression : XcmsSuccess); +} + + +/************************************************************************ + * * + * PUBLIC ROUTINES * + * * + ************************************************************************/ + +/* + * NAME + * XcmsConvertColors - Convert XcmsColor structures + * + * SYNOPSIS + */ +Status +XcmsConvertColors(ccc, pColors_in_out, nColors, targetFormat, pCompressed) + XcmsCCC ccc; + XcmsColor *pColors_in_out; + unsigned int nColors; + XcmsColorFormat targetFormat; + Bool *pCompressed; +/* + * DESCRIPTION + * Convert XcmsColor structures to another format + * + * RETURNS + * XcmsFailure if failed, + * XcmsSuccess if succeeded without gamut compression, + * XcmsSuccessWithCompression if succeeded with gamut + * compression. + * + */ +{ + XcmsColor clientWhitePt; + XcmsColor Color1; + XcmsColor *pColors_tmp; + int callWhiteAdjustProc = 0; + XcmsColorFormat format; + Status retval; + unsigned char contents_flag = 0x00; + unsigned int iColors; + + if (ccc == NULL || pColors_in_out == NULL || + !(ValidDIColorSpaceID(targetFormat) || + ValidDDColorSpaceID(ccc, targetFormat))) { + return(XcmsFailure); + } + + /* + * Check formats in color specification array + */ + format = pColors_in_out->format; + for (pColors_tmp = pColors_in_out, iColors = nColors; iColors; pColors_tmp++, iColors--) { + if (!(ValidDIColorSpaceID(pColors_tmp->format) || + ValidDDColorSpaceID(ccc, pColors_tmp->format))) { + return(XcmsFailure); + } + if (XCMS_DI_ID(pColors_tmp->format)) { + contents_flag |= DI_FORMAT; + } else { + contents_flag |= DD_FORMAT; + } + if (pColors_tmp->format != format) { + contents_flag |= MIX_FORMAT; + } + } + + /* + * Check if we need the Client White Point. + */ + if ((contents_flag & DI_FORMAT) || XCMS_DI_ID(targetFormat)) { + /* To proceed, we need to get the Client White Point */ + memcpy((char *)&clientWhitePt, (char *)&ccc->clientWhitePt, + sizeof(XcmsColor)); + if (clientWhitePt.format == XcmsUndefinedFormat) { + /* + * Client White Point is undefined, therefore set to the Screen + * White Point. + * Since Client White Point == Screen White Point, WhiteAdjustProc + * is not called. + */ + memcpy((char *)&clientWhitePt, + (char *)&ccc->pPerScrnInfo->screenWhitePt, + sizeof(XcmsColor)); + } else if ((ccc->whitePtAdjProc != NULL) && !_XcmsEqualWhitePts(ccc, + &clientWhitePt, ScreenWhitePointOfCCC(ccc))) { + /* + * Client White Point != Screen White Point, and WhiteAdjustProc + * is not NULL, therefore, will need to call it when + * converting between DI and DD specifications. + */ + callWhiteAdjustProc = 1; + } + } + + /* + * Make copy of array of color specifications + */ + if (nColors > 1) { + pColors_tmp = (XcmsColor *) Xmalloc(nColors * sizeof(XcmsColor)); + } else { + pColors_tmp = &Color1; + } + memcpy((char *)pColors_tmp, (char *)pColors_in_out, + nColors * sizeof(XcmsColor)); + + /* + * zero out pCompressed + */ + if (pCompressed) { + bzero((char *)pCompressed, nColors * sizeof(Bool)); + } + + if (contents_flag == DD_FORMAT || contents_flag == DI_FORMAT) { + /* + * ENTIRE ARRAY IS IN ONE FORMAT. + */ + if (XCMS_DI_ID(format) && XCMS_DI_ID(targetFormat)) { + /* + * DI-to-DI only conversion + */ + retval = _XcmsDIConvertColors(ccc, pColors_tmp, + &clientWhitePt, nColors, targetFormat); + } else if (XCMS_DD_ID(format) && XCMS_DD_ID(targetFormat)) { + /* + * DD-to-DD only conversion + * Since DD->DD there will be no compressed thus we can + * pass NULL instead of pCompressed. + */ + retval = _XcmsDDConvertColors(ccc, pColors_tmp, nColors, + targetFormat, (Bool *)NULL); + } else { + /* + * Otherwise we have: + * 1. Device-Independent to Device-Dependent Conversion + * OR + * 2. Device-Dependent to Device-Independent Conversion + * + * We need to go from oldFormat -> CIEXYZ -> targetFormat + * adjusting for white points as necessary. + */ + + if (XCMS_DI_ID(format)) { + /* + * 1. Device-Independent to Device-Dependent Conversion + */ + if (callWhiteAdjustProc) { + /* + * White Point Adjustment + * Client White Point to Screen White Point + */ + retval = (*ccc->whitePtAdjProc)(ccc, &clientWhitePt, + ScreenWhitePointOfCCC(ccc), targetFormat, + pColors_tmp, nColors, pCompressed); + } else { + if (_XcmsDIConvertColors(ccc, pColors_tmp, + &clientWhitePt, nColors, XcmsCIEXYZFormat) + == XcmsFailure) { + goto Failure; + } + retval = _XcmsDDConvertColors(ccc, pColors_tmp, nColors, + targetFormat, pCompressed); + } + } else { + /* + * 2. Device-Dependent to Device-Independent Conversion + */ + if (callWhiteAdjustProc) { + /* + * White Point Adjustment + * Screen White Point to Client White Point + */ + retval = (*ccc->whitePtAdjProc)(ccc, + ScreenWhitePointOfCCC(ccc), &clientWhitePt, + targetFormat, pColors_tmp, nColors, pCompressed); + } else { + /* + * Since DD->CIEXYZ, no compression takes place therefore + * we can pass NULL instead of pCompressed. + */ + if (_XcmsDDConvertColors(ccc, pColors_tmp, nColors, + XcmsCIEXYZFormat, (Bool *)NULL) == XcmsFailure) { + goto Failure; + } + retval = _XcmsDIConvertColors(ccc, pColors_tmp, + &clientWhitePt, nColors, targetFormat); + } + } + } + } else { + /* + * ARRAY HAS MIXED FORMATS. + */ + if ((contents_flag == (DI_FORMAT | MIX_FORMAT)) && + XCMS_DI_ID(targetFormat)) { + /* + * Convert from DI to DI in batches of contiguous formats + * + * Because DI->DI, WhiteAdjustProc not called. + */ + retval = ConvertMixedColors(ccc, pColors_tmp, &clientWhitePt, + nColors, targetFormat, (unsigned char)DI_FORMAT); + } else if ((contents_flag == (DD_FORMAT | MIX_FORMAT)) && + XCMS_DD_ID(targetFormat)) { + /* + * Convert from DD to DD in batches of contiguous formats + * + * Because DD->DD, WhiteAdjustProc not called. + */ + retval = ConvertMixedColors(ccc, pColors_tmp, + (XcmsColor *)NULL, nColors, targetFormat, + (unsigned char)DD_FORMAT); + } else if (XCMS_DI_ID(targetFormat)) { + /* + * We need to convert from DI-to-DI and DD-to-DI, therefore + * 1. convert DD specifications to CIEXYZ, then + * 2. convert all in batches to the target DI format. + * + * Note that ConvertMixedColors will call WhiteAdjustProc + * as necessary. + */ + + /* + * Convert only DD specifications in batches of contiguous formats + * to CIEXYZ + * + * Since DD->CIEXYZ, ConvertMixedColors will apply WhiteAdjustProc + * if required. + */ + retval = ConvertMixedColors(ccc, pColors_tmp, &clientWhitePt, + nColors, XcmsCIEXYZFormat, (unsigned char)DD_FORMAT); + + /* + * Because at this point we may have a mix of DI formats + * (e.g., CIEXYZ, CIELuv) we must convert the specs to the + * target DI format in batches of contiguous source formats. + */ + retval = ConvertMixedColors(ccc, pColors_tmp, &clientWhitePt, + nColors, targetFormat, (unsigned char)DI_FORMAT); + } else { + /* + * We need to convert from DI-to-DD and DD-to-DD, therefore + * 1. convert DI specifications to CIEXYZ, then + * 2. convert all to the DD target format. + * + * This allows white point adjustment and gamut compression + * to be applied to all the color specifications in one + * swoop if those functions do in fact modify the entire + * group of color specifications. + */ + + /* + * Convert in batches to CIEXYZ + * + * If DD->CIEXYZ, ConvertMixedColors will apply WhiteAdjustProc + * if required. + */ + if ((retval = ConvertMixedColors(ccc, pColors_tmp, &clientWhitePt, + nColors, XcmsCIEXYZFormat, + (unsigned char)(DI_FORMAT | DD_FORMAT))) == XcmsFailure) { + goto Failure; + } + + /* + * Convert all specifications (now in CIEXYZ format) to + * the target DD format. + * Since CIEXYZ->DD, compression MAY take place therefore + * we must pass pCompressed. + * Note that WhiteAdjustProc must be used if necessary. + */ + if (callWhiteAdjustProc) { + /* + * White Point Adjustment + * Client White Point to Screen White Point + */ + retval = (*ccc->whitePtAdjProc)(ccc, + &clientWhitePt, ScreenWhitePointOfCCC(ccc), + targetFormat, pColors_tmp, nColors, pCompressed); + } else { + retval = _XcmsDDConvertColors(ccc, pColors_tmp, nColors, + targetFormat, pCompressed); + } + } + } + + if (retval != XcmsFailure) { + memcpy((char *)pColors_in_out, (char *)pColors_tmp, + nColors * sizeof(XcmsColor)); + } + if (nColors > 1) { + Xfree((char *)pColors_tmp); + } + return(retval); + +Failure: + if (nColors > 1) { + Xfree((char *)pColors_tmp); + } + return(XcmsFailure); +} + + +/* + * NAME + * XcmsRegFormatOfPrefix + * + * SYNOPSIS + */ +XcmsColorFormat +_XcmsRegFormatOfPrefix(prefix) + char *prefix; +/* + * DESCRIPTION + * Returns a color space ID associated with the specified + * X Consortium registered color space prefix. + * + * RETURNS + * The color space ID if found; + * otherwise NULL. + */ +{ + XcmsRegColorSpaceEntry *pEntry = _XcmsRegColorSpaces; + + while (pEntry->prefix != NULL) { + if (strcmp(prefix, pEntry->prefix) == 0) { + return(pEntry->id); + } + pEntry++; + } + return(XcmsUndefinedFormat); +} diff --git a/src/xcms/HVC.c b/src/xcms/HVC.c new file mode 100644 index 00000000..26bca265 --- /dev/null +++ b/src/xcms/HVC.c @@ -0,0 +1,611 @@ +/* $Xorg: HVC.c,v 1.3 2000/08/17 19:44:36 cpqbld Exp $ */ + +/* + * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. + * All Rights Reserved + * + * This file is a component of an X Window System-specific implementation + * of Xcms based on the TekColor Color Management System. TekColor is a + * trademark of Tektronix, Inc. The term "TekHVC" designates a particular + * color space that is the subject of U.S. Patent No. 4,985,853 (equivalent + * foreign patents pending). Permission is hereby granted to use, copy, + * modify, sell, and otherwise distribute this software and its + * documentation for any purpose and without fee, provided that: + * + * 1. This copyright, permission, and disclaimer notice is reproduced in + * all copies of this software and any modification thereof and in + * supporting documentation; + * 2. Any color-handling application which displays TekHVC color + * cooordinates identifies these as TekHVC color coordinates in any + * interface that displays these coordinates and in any associated + * documentation; + * 3. The term "TekHVC" is always used, and is only used, in association + * with the mathematical derivations of the TekHVC Color Space, + * including those provided in this file and any equivalent pathways and + * mathematical derivations, regardless of digital (e.g., floating point + * or integer) representation. + * + * Tektronix makes no representation about the suitability of this software + * for any purpose. It is provided "as is" and with all faults. + * + * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, + * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX 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 THE PERFORMANCE OF THIS SOFTWARE. + * + * NAME + * TekHVC.c + * + * DESCRIPTION + * This file contains routines that support the TekHVC + * color space to include conversions to and from the CIE + * XYZ space. + * + * DOCUMENTATION + * "TekColor Color Management System, System Implementor's Manual" + */ + +#include "Xlibint.h" +#include "Xcmsint.h" +#include <X11/Xos.h> +#include <math.h> + +/* + * DEFINES + */ +#define u_BR 0.7127 /* u' Best Red */ +#define v_BR 0.4931 /* v' Best Red */ +#define EPS 0.001 +#define CHROMA_SCALE_FACTOR 7.50725 +#ifndef PI +# ifdef M_PI +# define PI M_PI +# else +# define PI 3.14159265358979323846264338327950 +# endif +#endif +#ifndef degrees +# define degrees(r) ((XcmsFloat)(r) * 180.0 / PI) +#endif /* degrees */ +#ifndef radians +# define radians(d) ((XcmsFloat)(d) * PI / 180.0) +#endif /* radians */ + +/************************************************************************* + * Note: The DBL_EPSILON for ANSI is 1e-5 so my checks need to take + * this into account. If your DBL_EPSILON is different then + * adjust this define. + * + * Also note that EPS is the error factor in the calculations + * This may need to be the same as XMY_DBL_EPSILON in + * some implementations. + **************************************************************************/ +#ifdef DBL_EPSILON +# define XMY_DBL_EPSILON DBL_EPSILON +#else +# define XMY_DBL_EPSILON 0.00001 +#endif + +/* + * EXTERNS + */ + +extern char _XcmsTekHVC_prefix[]; + +/* + * FORWARD DECLARATIONS + */ + +static int TekHVC_ParseString(); +static Status XcmsTekHVC_ValidSpec(); + + +/* + * LOCAL VARIABLES + */ + + /* + * NULL terminated list of functions applied to get from TekHVC to CIEXYZ + */ +static XcmsConversionProc Fl_TekHVC_to_CIEXYZ[] = { + XcmsTekHVCToCIEuvY, + XcmsCIEuvYToCIEXYZ, + NULL +}; + + /* + * NULL terminated list of functions applied to get from CIEXYZ to TekHVC + */ +static XcmsConversionProc Fl_CIEXYZ_to_TekHVC[] = { + XcmsCIEXYZToCIEuvY, + XcmsCIEuvYToTekHVC, + NULL +}; + +/* + * GLOBALS + */ + + /* + * TekHVC Color Space + */ +XcmsColorSpace XcmsTekHVCColorSpace = + { + _XcmsTekHVC_prefix, /* prefix */ + XcmsTekHVCFormat, /* id */ + TekHVC_ParseString, /* parseString */ + Fl_TekHVC_to_CIEXYZ, /* to_CIEXYZ */ + Fl_CIEXYZ_to_TekHVC, /* from_CIEXYZ */ + 1 + }; + + + + +/************************************************************************ + * * + * PRIVATE ROUTINES * + * * + ************************************************************************/ + +/* + * NAME + * TekHVC_ParseString + * + * SYNOPSIS + */ +static int +TekHVC_ParseString(spec, pColor) + register char *spec; + XcmsColor *pColor; +/* + * DESCRIPTION + * This routines takes a string and attempts to convert + * it into a XcmsColor structure with XcmsTekHVCFormat. + * The assumed TekHVC string syntax is: + * TekHVC:<H>/<V>/<C> + * Where H, V, and C are in string input format for floats + * consisting of: + * a. an optional sign + * b. a string of numbers possibly containing a decimal point, + * c. an optional exponent field containing an 'E' or 'e' + * followed by a possibly signed integer string. + * + * RETURNS + * XcmsFailure if invalid; + * XcmsSuccess if valid. + */ +{ + int n; + char *pchar; + + if ((pchar = strchr(spec, ':')) == NULL) { + return(XcmsFailure); + } + n = (int)(pchar - spec); + + /* + * Check for proper prefix. + */ + if (strncmp(spec, _XcmsTekHVC_prefix, n) != 0) { + return(XcmsFailure); + } + + /* + * Attempt to parse the value portion. + */ + if (sscanf(spec + n + 1, "%lf/%lf/%lf", + &pColor->spec.TekHVC.H, + &pColor->spec.TekHVC.V, + &pColor->spec.TekHVC.C) != 3) { + return(XcmsFailure); + } + pColor->format = XcmsTekHVCFormat; + pColor->pixel = 0; + return(XcmsTekHVC_ValidSpec(pColor)); +} + + +/* + * NAME + * ThetaOffset -- compute thetaOffset + * + * SYNOPSIS + */ +static int +ThetaOffset(pWhitePt, pThetaOffset) + XcmsColor *pWhitePt; + XcmsFloat *pThetaOffset; +/* + * DESCRIPTION + * This routine computes the theta offset of a given + * white point, i.e. XcmsColor. It is used in both this + * conversion and the printer conversions. + * + * RETURNS + * 0 if failed. + * 1 if succeeded with no modifications. + * + * ASSUMPTIONS + * Assumes: + * pWhitePt != NULL + * pWhitePt->format == XcmsCIEuvYFormat + * + */ +{ + double div, slopeuv; + + if (pWhitePt == NULL || pWhitePt->format != XcmsCIEuvYFormat) { + return(0); + } + + if ((div = u_BR - pWhitePt->spec.CIEuvY.u_prime) == 0.0) { + return(0); + } + slopeuv = (v_BR - pWhitePt->spec.CIEuvY.v_prime) / div; + *pThetaOffset = degrees(XCMS_ATAN(slopeuv)); + return(1); +} + + + +/************************************************************************ + * * + * PUBLIC ROUTINES * + * * + ************************************************************************/ + +/* + * NAME + * XcmsTekHVC_ValidSpec() + * + * SYNOPSIS + */ +static int +XcmsTekHVC_ValidSpec(pColor) + XcmsColor *pColor; +/* + * DESCRIPTION + * Checks if values in the color specification are valid. + * Also brings hue into the range 0.0 <= Hue < 360.0 + * + * RETURNS + * 0 if not valid. + * 1 if valid. + * + */ +{ + if (pColor->format != XcmsTekHVCFormat) { + return(XcmsFailure); + } + if (pColor->spec.TekHVC.V < (0.0 - XMY_DBL_EPSILON) + || pColor->spec.TekHVC.V > (100.0 + XMY_DBL_EPSILON) + || (pColor->spec.TekHVC.C < 0.0 - XMY_DBL_EPSILON)) { + return(XcmsFailure); + } + + if (pColor->spec.TekHVC.V < 0.0) { + pColor->spec.TekHVC.V = 0.0 + XMY_DBL_EPSILON; + } else if (pColor->spec.TekHVC.V > 100.0) { + pColor->spec.TekHVC.V = 100.0 - XMY_DBL_EPSILON; + } + + if (pColor->spec.TekHVC.C < 0.0) { + pColor->spec.TekHVC.C = 0.0 - XMY_DBL_EPSILON; + } + + while (pColor->spec.TekHVC.H < 0.0) { + pColor->spec.TekHVC.H += 360.0; + } + while (pColor->spec.TekHVC.H >= 360.0) { + pColor->spec.TekHVC.H -= 360.0; + } + return(XcmsSuccess); +} + +/* + * NAME + * XcmsTekHVCToCIEuvY - convert TekHVC to CIEuvY + * + * SYNOPSIS + */ +Status +XcmsTekHVCToCIEuvY(ccc, pHVC_WhitePt, pColors_in_out, nColors) + XcmsCCC ccc; + XcmsColor *pHVC_WhitePt; + XcmsColor *pColors_in_out; + unsigned int nColors; +/* + * DESCRIPTION + * Transforms an array of TekHVC color specifications, given + * their associated white point, to CIECIEuvY.color + * specifications. + * + * RETURNS + * XcmsFailure if failed, XcmsSuccess otherwise. + * + */ +{ + XcmsFloat thetaOffset; + XcmsColor *pColor = pColors_in_out; + XcmsColor whitePt; + XcmsCIEuvY uvY_return; + XcmsFloat tempHue, u, v; + XcmsFloat tmpVal; + register int i; + + /* + * Check arguments + */ + if (pHVC_WhitePt == NULL || pColors_in_out == NULL) { + return(XcmsFailure); + } + + /* + * Make sure white point is in CIEuvY form + */ + if (pHVC_WhitePt->format != XcmsCIEuvYFormat) { + /* Make copy of the white point because we're going to modify it */ + memcpy((char *)&whitePt, (char *)pHVC_WhitePt, sizeof(XcmsColor)); + if (!_XcmsDIConvertColors(ccc, &whitePt, (XcmsColor *)NULL, 1, + XcmsCIEuvYFormat)) { + return(XcmsFailure); + } + pHVC_WhitePt = &whitePt; + } + /* Make sure it is a white point, i.e., Y == 1.0 */ + if (pHVC_WhitePt->spec.CIEuvY.Y != 1.0) { + return(XcmsFailure); + } + + /* Get the thetaOffset */ + if (!ThetaOffset(pHVC_WhitePt, &thetaOffset)) { + return(XcmsFailure); + } + + /* + * Now convert each XcmsColor structure to CIEXYZ form + */ + for (i = 0; i < nColors; i++, pColor++) { + + /* Make sure original format is TekHVC and is valid */ + if (!XcmsTekHVC_ValidSpec(pColor)) { + return(XcmsFailure); + } + + if (pColor->spec.TekHVC.V == 0.0 || pColor->spec.TekHVC.V == 100.0) { + if (pColor->spec.TekHVC.V == 100.0) { + uvY_return.Y = 1.0; + } else { /* pColor->spec.TekHVC.V == 0.0 */ + uvY_return.Y = 0.0; + } + uvY_return.u_prime = pHVC_WhitePt->spec.CIEuvY.u_prime; + uvY_return.v_prime = pHVC_WhitePt->spec.CIEuvY.v_prime; + } else { + + /* Find the hue based on the white point offset */ + tempHue = pColor->spec.TekHVC.H + thetaOffset; + + while (tempHue < 0.0) { + tempHue += 360.0; + } + while (tempHue >= 360.0) { + tempHue -= 360.0; + } + + tempHue = radians(tempHue); + + /* Calculate u'v' for the obtained hue */ + u = (XcmsFloat) ((XCMS_COS(tempHue) * pColor->spec.TekHVC.C) / + (pColor->spec.TekHVC.V * (double)CHROMA_SCALE_FACTOR)); + v = (XcmsFloat) ((XCMS_SIN(tempHue) * pColor->spec.TekHVC.C) / + (pColor->spec.TekHVC.V * (double)CHROMA_SCALE_FACTOR)); + + /* Based on the white point get the offset from best red */ + uvY_return.u_prime = u + pHVC_WhitePt->spec.CIEuvY.u_prime; + uvY_return.v_prime = v + pHVC_WhitePt->spec.CIEuvY.v_prime; + + /* Calculate the Y value based on the L* = V. */ + if (pColor->spec.TekHVC.V < 7.99953624) { + uvY_return.Y = pColor->spec.TekHVC.V / 903.29; + } else { + tmpVal = (pColor->spec.TekHVC.V + 16.0) / 116.0; + uvY_return.Y = tmpVal * tmpVal * tmpVal; /* tmpVal ** 3 */ + } + } + + /* Copy result to pColor */ + memcpy((char *)&pColor->spec, (char *)&uvY_return, sizeof(XcmsCIEuvY)); + + /* Identify that the format is now CIEuvY */ + pColor->format = XcmsCIEuvYFormat; + } + return(XcmsSuccess); +} + + +/* + * NAME + * XcmsCIEuvYToTekHVC - convert CIEuvY to TekHVC + * + * SYNOPSIS + */ +Status +XcmsCIEuvYToTekHVC(ccc, pHVC_WhitePt, pColors_in_out, nColors) + XcmsCCC ccc; + XcmsColor *pHVC_WhitePt; + XcmsColor *pColors_in_out; + unsigned int nColors; +/* + * DESCRIPTION + * Transforms an array of CIECIEuvY.color specifications, given + * their assiciated white point, to TekHVC specifications. + * + * RETURNS + * XcmsFailure if failed, XcmsSuccess otherwise. + * + */ +{ + XcmsFloat theta, L2, u, v, nThetaLow, nThetaHigh; + XcmsFloat thetaOffset; + XcmsColor *pColor = pColors_in_out; + XcmsColor whitePt; + XcmsTekHVC HVC_return; + register int i; + + /* + * Check arguments + */ + if (pHVC_WhitePt == NULL || pColors_in_out == NULL) { + return(XcmsFailure); + } + + /* + * Make sure white point is in CIEuvY form + */ + if (pHVC_WhitePt->format != XcmsCIEuvYFormat) { + /* Make copy of the white point because we're going to modify it */ + memcpy((char *)&whitePt, (char *)pHVC_WhitePt, sizeof(XcmsColor)); + if (!_XcmsDIConvertColors(ccc, &whitePt, (XcmsColor *)NULL, 1, + XcmsCIEuvYFormat)) { + return(XcmsFailure); + } + pHVC_WhitePt = &whitePt; + } + /* Make sure it is a white point, i.e., Y == 1.0 */ + if (pHVC_WhitePt->spec.CIEuvY.Y != 1.0) { + return(XcmsFailure); + } + if (!ThetaOffset(pHVC_WhitePt, &thetaOffset)) { + return(XcmsFailure); + } + + /* + * Now convert each XcmsColor structure to CIEXYZ form + */ + for (i = 0; i < nColors; i++, pColor++) { + if (!_XcmsCIEuvY_ValidSpec(pColor)) { + return(XcmsFailure); + } + + /* Use the white point offset to determine HVC */ + u = pColor->spec.CIEuvY.u_prime - pHVC_WhitePt->spec.CIEuvY.u_prime; + v = pColor->spec.CIEuvY.v_prime - pHVC_WhitePt->spec.CIEuvY.v_prime; + + /* Calculate the offset */ + if (u == 0.0) { + theta = 0.0; + } else { + theta = v / u; + theta = (XcmsFloat) XCMS_ATAN((double)theta); + theta = degrees(theta); + } + + nThetaLow = 0.0; + nThetaHigh = 360.0; + if (u > 0.0 && v > 0.0) { + nThetaLow = 0.0; + nThetaHigh = 90.0; + } else if (u < 0.0 && v > 0.0) { + nThetaLow = 90.0; + nThetaHigh = 180.0; + } else if (u < 0.0 && v < 0.0) { + nThetaLow = 180.0; + nThetaHigh = 270.0; + } else if (u > 0.0 && v < 0.0) { + nThetaLow = 270.0; + nThetaHigh = 360.0; + } + while (theta < nThetaLow) { + theta += 90.0; + } + while (theta >= nThetaHigh) { + theta -= 90.0; + } + + /* calculate the L value from the given Y */ + L2 = (pColor->spec.CIEuvY.Y < 0.008856) + ? + (pColor->spec.CIEuvY.Y * 903.29) + : + ((XcmsFloat)(XCMS_CUBEROOT(pColor->spec.CIEuvY.Y) * 116.0) - 16.0); + HVC_return.C = L2 * CHROMA_SCALE_FACTOR * XCMS_SQRT((double) ((u * u) + (v * v))); + if (HVC_return.C < 0.0) { + theta = 0.0; + } + HVC_return.V = L2; + HVC_return.H = theta - thetaOffset; + + /* + * If this is within the error margin let some other routine later + * in the chain worry about the slop in the calculations. + */ + while (HVC_return.H < -EPS) { + HVC_return.H += 360.0; + } + while (HVC_return.H >= 360.0 + EPS) { + HVC_return.H -= 360.0; + } + + /* Copy result to pColor */ + memcpy((char *)&pColor->spec, (char *)&HVC_return, sizeof(XcmsTekHVC)); + + /* Identify that the format is now CIEuvY */ + pColor->format = XcmsTekHVCFormat; + } + return(XcmsSuccess); +} + + +/* + * NAME + * _XcmsTekHVC_CheckModify + * + * SYNOPSIS + */ +int +_XcmsTekHVC_CheckModify(pColor) + XcmsColor *pColor; +/* + * DESCRIPTION + * Checks if values in the color specification are valid. + * If they are not it modifies the values. + * Also brings hue into the range 0.0 <= Hue < 360.0 + * + * RETURNS + * 0 if not valid. + * 1 if valid. + * + */ +{ + int n; + + /* For now only use the TekHVC numbers as inputs */ + if (pColor->format != XcmsTekHVCFormat) { + return(0); + } + + if (pColor->spec.TekHVC.V < 0.0) { + pColor->spec.TekHVC.V = 0.0 + XMY_DBL_EPSILON; + } else if (pColor->spec.TekHVC.V > 100.0) { + pColor->spec.TekHVC.V = 100.0 - XMY_DBL_EPSILON; + } + + if (pColor->spec.TekHVC.C < 0.0) { + pColor->spec.TekHVC.C = 0.0 - XMY_DBL_EPSILON; + } + + if (pColor->spec.TekHVC.H < 0.0) { + n = -pColor->spec.TekHVC.H / 360.0; + pColor->spec.TekHVC.H += (n + 1) * 360.0; + if (pColor->spec.TekHVC.H >= 360.0) + pColor->spec.TekHVC.H -= 360.0; + } else if (pColor->spec.TekHVC.H >= 360.0) { + n = pColor->spec.TekHVC.H / 360.0; + pColor->spec.TekHVC.H -= n * 360.0; + } + return(1); +} diff --git a/src/xcms/HVCGcC.c b/src/xcms/HVCGcC.c new file mode 100644 index 00000000..26a3f121 --- /dev/null +++ b/src/xcms/HVCGcC.c @@ -0,0 +1,153 @@ +/* $Xorg: HVCGcC.c,v 1.3 2000/08/17 19:44:36 cpqbld Exp $ */ + +/* + * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. + * All Rights Reserved + * + * This file is a component of an X Window System-specific implementation + * of Xcms based on the TekColor Color Management System. TekColor is a + * trademark of Tektronix, Inc. The term "TekHVC" designates a particular + * color space that is the subject of U.S. Patent No. 4,985,853 (equivalent + * foreign patents pending). Permission is hereby granted to use, copy, + * modify, sell, and otherwise distribute this software and its + * documentation for any purpose and without fee, provided that: + * + * 1. This copyright, permission, and disclaimer notice is reproduced in + * all copies of this software and any modification thereof and in + * supporting documentation; + * 2. Any color-handling application which displays TekHVC color + * cooordinates identifies these as TekHVC color coordinates in any + * interface that displays these coordinates and in any associated + * documentation; + * 3. The term "TekHVC" is always used, and is only used, in association + * with the mathematical derivations of the TekHVC Color Space, + * including those provided in this file and any equivalent pathways and + * mathematical derivations, regardless of digital (e.g., floating point + * or integer) representation. + * + * Tektronix makes no representation about the suitability of this software + * for any purpose. It is provided "as is" and with all faults. + * + * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, + * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX 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 THE PERFORMANCE OF THIS SOFTWARE. + * + * NAME + * TekHVCGcC.c + * + * DESCRIPTION + * Source for XcmsTekHVCClipC() gamut compression routine. + * + */ + +#include "Xlibint.h" +#include "Xcmsint.h" + +/* + * EXTERNS + */ +extern XcmsColorSpace XcmsTekHVCColorSpace; +extern XcmsFunctionSet XcmsLinearRGBFunctionSet; + + + +/************************************************************************ + * * + * PUBLIC ROUTINES * + * * + ************************************************************************/ + +/* + * NAME + * XcmsTekHVCClipC - Reduce the chroma for a hue and value + * + * SYNOPSIS + */ +/* ARGSUSED */ +Status +XcmsTekHVCClipC (ccc, pColors_in_out, nColors, i, pCompressed) + XcmsCCC ccc; + XcmsColor *pColors_in_out; + unsigned int nColors; + unsigned int i; + Bool *pCompressed; +/* + * DESCRIPTION + * Reduce the Chroma for a specific hue and value to + * to bring the given color into the gamut of the + * specified device. As required of gamut compression + * functions in Xcms, this routine returns pColor_in_out + * in XcmsCIEXYZFormat on successful completion. + * + * Since this routine works with the value within + * pColor_in_out intermediate results may be returned + * even though it may be invalid. + * + * RETURNS + * XcmsFailure - Failure + * XcmsSuccess - Succeeded + * + */ +{ + Status retval; + XcmsColor *pColor; + + /* + * Color specification passed as input can be assumed to: + * 1. Be in XcmsCIEXYZFormat + * 2. Already be white point adjusted for the Screen White Point. + * This means that the white point now associated with this + * color spec is the Screen White Point (even if the + * ccc->clientWhitePt differs). + */ + + /* + * Insure TekHVC installed + */ + if (XcmsAddColorSpace(&XcmsTekHVCColorSpace) == XcmsFailure) { + return(XcmsFailure); + } + + pColor = pColors_in_out + i; + + if (ccc->visual->class < StaticColor && + FunctionSetOfCCC(ccc) != (XPointer) &XcmsLinearRGBFunctionSet) { + /* + * GRAY ! + */ + _XcmsDIConvertColors(ccc, pColor, &ccc->pPerScrnInfo->screenWhitePt, + 1, XcmsTekHVCFormat); + pColor->spec.TekHVC.H = pColor->spec.TekHVC.C = 0.0; + _XcmsDIConvertColors(ccc, pColor, &ccc->pPerScrnInfo->screenWhitePt, + 1, XcmsCIEXYZFormat); + if (pCompressed) { + *(pCompressed + i) = True; + } + return(XcmsSuccess); + } else { + if (pColor->format != XcmsTekHVCFormat) { + if (_XcmsDIConvertColors(ccc, pColor, + &ccc->pPerScrnInfo->screenWhitePt, 1, XcmsTekHVCFormat) + == XcmsFailure) { + return(XcmsFailure); + } + } + if (XcmsTekHVCQueryMaxC(ccc, + pColor->spec.TekHVC.H, + pColor->spec.TekHVC.V, + pColor) + == XcmsFailure) { + return(XcmsFailure); + } + retval = _XcmsDIConvertColors(ccc, pColor, + &ccc->pPerScrnInfo->screenWhitePt, 1, XcmsCIEXYZFormat); + if (retval != XcmsFailure && pCompressed != NULL) { + *(pCompressed + i) = True; + } + return(retval); + } +} diff --git a/src/xcms/HVCGcV.c b/src/xcms/HVCGcV.c new file mode 100644 index 00000000..7b062123 --- /dev/null +++ b/src/xcms/HVCGcV.c @@ -0,0 +1,206 @@ +/* $Xorg: HVCGcV.c,v 1.3 2000/08/17 19:44:36 cpqbld Exp $ */ + +/* + * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. + * All Rights Reserved + * + * This file is a component of an X Window System-specific implementation + * of Xcms based on the TekColor Color Management System. TekColor is a + * trademark of Tektronix, Inc. The term "TekHVC" designates a particular + * color space that is the subject of U.S. Patent No. 4,985,853 (equivalent + * foreign patents pending). Permission is hereby granted to use, copy, + * modify, sell, and otherwise distribute this software and its + * documentation for any purpose and without fee, provided that: + * + * 1. This copyright, permission, and disclaimer notice is reproduced in + * all copies of this software and any modification thereof and in + * supporting documentation; + * 2. Any color-handling application which displays TekHVC color + * cooordinates identifies these as TekHVC color coordinates in any + * interface that displays these coordinates and in any associated + * documentation; + * 3. The term "TekHVC" is always used, and is only used, in association + * with the mathematical derivations of the TekHVC Color Space, + * including those provided in this file and any equivalent pathways and + * mathematical derivations, regardless of digital (e.g., floating point + * or integer) representation. + * + * Tektronix makes no representation about the suitability of this software + * for any purpose. It is provided "as is" and with all faults. + * + * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, + * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX 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 THE PERFORMANCE OF THIS SOFTWARE. + * + * NAME + * TekHVCGcV.c + * + * DESCRIPTION + * Source for XcmsTekHVCClipV() gamut compression routine. + * + */ + +#include "Xlibint.h" +#include "Xcmsint.h" + +/* + * EXTERNS + */ +extern Status _XcmsTekHVC_CheckModify(); +extern XcmsColorSpace XcmsTekHVCColorSpace; +extern XcmsFunctionSet XcmsLinearRGBFunctionSet; + + + +/************************************************************************ + * * + * PUBLIC ROUTINES * + * * + ************************************************************************/ + +/* + * NAME + * XcmsTekHVCClipV - Return the closest value + * + * SYNOPSIS + */ +/* ARGSUSED */ +Status +XcmsTekHVCClipV (ccc, pColors_in_out, nColors, i, pCompressed) + XcmsCCC ccc; + XcmsColor *pColors_in_out; + unsigned int nColors; + unsigned int i; + Bool *pCompressed; +/* + * DESCRIPTION + * Return the closest value for a specific hue and chroma. + * This routine takes any color as input and outputs + * a CIE XYZ color. + * + * Since this routine works with the value within + * pColor_in_out intermediate results may be returned + * even though it may be invalid. + * + * RETURNS + * XcmsFailure - Failure + * XcmsSuccess - Succeeded + * + */ +{ + XcmsColor *pColor; + XcmsColor hvc_max; + XcmsCCCRec myCCC; + Status retval; + + /* + * Insure TekHVC installed + */ + if (XcmsAddColorSpace(&XcmsTekHVCColorSpace) == XcmsFailure) { + return(XcmsFailure); + } + + /* Use my own CCC */ + memcpy ((char *)&myCCC, (char *)ccc, sizeof(XcmsCCCRec)); + myCCC.clientWhitePt.format = XcmsUndefinedFormat;/* Inherit Screen WP */ + myCCC.gamutCompProc = (XcmsCompressionProc)NULL;/* no gamut compression */ + + /* + * Color specification passed as input can be assumed to: + * 1. Be in XcmsCIEXYZFormat + * 2. Already be white point adjusted for the Screen White Point. + * This means that the white point now associated with this + * color spec is the Screen White Point (even if the + * ccc->clientWhitePt differs). + */ + + pColor = pColors_in_out + i; + + if (ccc->visual->class < StaticColor && + FunctionSetOfCCC(ccc) != (XPointer) &XcmsLinearRGBFunctionSet) { + /* + * GRAY ! + */ + return(XcmsFailure); + } else { + /* Convert from CIEXYZ to TekHVC format */ + if (_XcmsDIConvertColors(&myCCC, pColor, + &myCCC.pPerScrnInfo->screenWhitePt, 1, XcmsTekHVCFormat) + == XcmsFailure) { + return(XcmsFailure); + } + + /* check to make sure we have a valid TekHVC number */ + if (!_XcmsTekHVC_CheckModify (pColor)) { + return (XcmsFailure); + } + + /* Step 1: compute the maximum value and chroma for this hue. */ + /* This copy may be overkill but it preserves the pixel etc. */ + memcpy((char *)&hvc_max, (char *)pColor, sizeof(XcmsColor)); + if (_XcmsTekHVCQueryMaxVCRGB (&myCCC, hvc_max.spec.TekHVC.H, &hvc_max, + (XcmsRGBi *)NULL) == XcmsFailure) { + return (XcmsFailure); + } + + /* Now check and return the appropriate value */ + if (pColor->spec.TekHVC.C == hvc_max.spec.TekHVC.C) { + /* When the chroma input is equal to the maximum chroma */ + /* merely return the value for that chroma. */ + pColor->spec.TekHVC.V = hvc_max.spec.TekHVC.V; + if (!_XcmsTekHVC_CheckModify (pColor)) { + return (XcmsFailure); + } + retval = _XcmsDIConvertColors(&myCCC, pColor, + &myCCC.pPerScrnInfo->screenWhitePt, 1, XcmsCIEXYZFormat); + } else if (pColor->spec.TekHVC.C > hvc_max.spec.TekHVC.C) { + /* When the chroma input is greater than the maximum chroma */ + /* merely return the value and chroma for the given hue. */ + pColor->spec.TekHVC.C = hvc_max.spec.TekHVC.C; + pColor->spec.TekHVC.V = hvc_max.spec.TekHVC.V; + return (XcmsFailure); + } else if (pColor->spec.TekHVC.V < hvc_max.spec.TekHVC.V) { + /* When the value input is less than the maximum value point */ + /* compute the intersection of the line from 0,0 to max_V, max_C */ + /* using the chroma input. */ + pColor->spec.TekHVC.V = pColor->spec.TekHVC.C * + hvc_max.spec.TekHVC.V / hvc_max.spec.TekHVC.C; + if (pColor->spec.TekHVC.V >= hvc_max.spec.TekHVC.V) { + pColor->spec.TekHVC.C = hvc_max.spec.TekHVC.C; + pColor->spec.TekHVC.V = hvc_max.spec.TekHVC.V; + } + if (!_XcmsTekHVC_CheckModify (pColor)) { + return (XcmsFailure); + } + retval = _XcmsDIConvertColors(&myCCC, pColor, + &myCCC.pPerScrnInfo->screenWhitePt, 1, XcmsCIEXYZFormat); + } else { + /* When the value input is greater than the maximum value point */ + /* use HvcMaxValue to find the maximum value for the given chroma. */ + if (pColor->format != XcmsTekHVCFormat) { + if (_XcmsDIConvertColors(ccc, pColor, + &ccc->pPerScrnInfo->screenWhitePt, 1, XcmsCIEXYZFormat) + == XcmsFailure) { + return(XcmsFailure); + } + } + if (XcmsTekHVCQueryMaxV(&myCCC, + pColor->spec.TekHVC.H, + pColor->spec.TekHVC.C, + pColor) + == XcmsFailure) { + return (XcmsFailure); + } + retval = _XcmsDIConvertColors(&myCCC, pColor, + &myCCC.pPerScrnInfo->screenWhitePt, 1, XcmsCIEXYZFormat); + } + if (retval != XcmsFailure && pCompressed != NULL) { + *(pCompressed + i) = True; + } + return(retval); + } +} diff --git a/src/xcms/HVCGcVC.c b/src/xcms/HVCGcVC.c new file mode 100644 index 00000000..00d09b2a --- /dev/null +++ b/src/xcms/HVCGcVC.c @@ -0,0 +1,267 @@ +/* $Xorg: HVCGcVC.c,v 1.3 2000/08/17 19:44:36 cpqbld Exp $ */ + +/* + * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. + * All Rights Reserved + * + * This file is a component of an X Window System-specific implementation + * of Xcms based on the TekColor Color Management System. TekColor is a + * trademark of Tektronix, Inc. The term "TekHVC" designates a particular + * color space that is the subject of U.S. Patent No. 4,985,853 (equivalent + * foreign patents pending). Permission is hereby granted to use, copy, + * modify, sell, and otherwise distribute this software and its + * documentation for any purpose and without fee, provided that: + * + * 1. This copyright, permission, and disclaimer notice is reproduced in + * all copies of this software and any modification thereof and in + * supporting documentation; + * 2. Any color-handling application which displays TekHVC color + * cooordinates identifies these as TekHVC color coordinates in any + * interface that displays these coordinates and in any associated + * documentation; + * 3. The term "TekHVC" is always used, and is only used, in association + * with the mathematical derivations of the TekHVC Color Space, + * including those provided in this file and any equivalent pathways and + * mathematical derivations, regardless of digital (e.g., floating point + * or integer) representation. + * + * Tektronix makes no representation about the suitability of this software + * for any purpose. It is provided "as is" and with all faults. + * + * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, + * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX 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 THE PERFORMANCE OF THIS SOFTWARE. + * + * NAME + * TekHVCGcVC.c + * + * DESCRIPTION + * Source for XcmsTekHVCClipVC() gamut + * compression function. + */ + +#include "Xlibint.h" +#include "Xcmsint.h" +#include <math.h> + +/* + * INTERNALS + * Internal defines that need NOT be exported to any package or + * program using this package. + */ +#define MAXBISECTCOUNT 100 + +/* + * EXTERNS + */ +extern int _XcmsTekHVC_CheckModify(); +extern Status _XcmsTekHVCQueryMaxVCRGB(); +extern XcmsColorSpace XcmsTekHVCColorSpace; +extern XcmsFunctionSet XcmsLinearRGBFunctionSet; + + +/************************************************************************ + * * + * PUBLIC ROUTINES * + * * + ************************************************************************/ + +/* + * NAME + * XcmsTekHVCClipVC - Return the closest value and chroma + * + * SYNOPSIS + */ +/* ARGSUSED */ +Status +XcmsTekHVCClipVC (ccc, pColors_in_out, nColors, i, pCompressed) + XcmsCCC ccc; + XcmsColor *pColors_in_out; + unsigned int nColors; + unsigned int i; + Bool *pCompressed; +/* + * DESCRIPTION + * This routine will find the closest value and chroma + * for a specific hue. The color input is converted to + * HVC format and returned as CIE XYZ format. + * + * Since this routine works with the value within + * pColor_in_out intermediate results may be returned + * even though it may be invalid. + * + * RETURNS + * XcmsFailure - Failure + * XcmsSuccess - Succeeded + * + */ +{ + Status retval; + XcmsCCCRec myCCC; + XcmsColor *pColor; + XcmsColor hvc_max; + XcmsRGBi rgb_max; + int nCount, nMaxCount, nI, nILast; + XcmsFloat Chroma, Value, bestChroma, bestValue, nT, saveDist, tmpDist; + + /* + * Insure TekHVC installed + */ + if (XcmsAddColorSpace(&XcmsTekHVCColorSpace) == XcmsFailure) { + return(XcmsFailure); + } + + /* Use my own CCC */ + memcpy ((char *)&myCCC, (char *)ccc, sizeof(XcmsCCCRec)); + myCCC.clientWhitePt.format = XcmsUndefinedFormat;/* inherit screen white pt */ + myCCC.gamutCompProc = (XcmsCompressionProc)NULL;/* no gamut compression func */ + + /* + * Color specification passed as input can be assumed to: + * 1. Be in XcmsCIEXYZFormat + * 2. Already be white point adjusted for the Screen White Point. + * This means that the white point now associated with this + * color spec is the Screen White Point (even if the + * ccc->clientWhitePt differs). + */ + + pColor = pColors_in_out + i; + + if (ccc->visual->class < StaticColor && + FunctionSetOfCCC(ccc) != (XPointer) &XcmsLinearRGBFunctionSet) { + /* + * GRAY ! + */ + _XcmsDIConvertColors(ccc, pColor, &ccc->pPerScrnInfo->screenWhitePt, + 1, XcmsTekHVCFormat); + pColor->spec.TekHVC.H = pColor->spec.TekHVC.C = 0.0; + _XcmsDIConvertColors(ccc, pColor, &ccc->pPerScrnInfo->screenWhitePt, + 1, XcmsCIEXYZFormat); + if (pCompressed) { + *(pCompressed + i) = True; + } + return(XcmsSuccess); + } else { + /* Convert from CIEXYZ to TekHVC format */ + if (_XcmsDIConvertColors(&myCCC, pColor, + &myCCC.pPerScrnInfo->screenWhitePt, 1, XcmsTekHVCFormat) + == XcmsFailure) { + return(XcmsFailure); + } + + if (!_XcmsTekHVC_CheckModify(pColor)) { + return (XcmsFailure); + } + + /* Step 1: compute the maximum value and chroma for this hue. */ + /* This copy may be overkill but it preserves the pixel etc. */ + memcpy((char *)&hvc_max, (char *)pColor, sizeof(XcmsColor)); + if (_XcmsTekHVCQueryMaxVCRGB (&myCCC, hvc_max.spec.TekHVC.H, &hvc_max, + &rgb_max) == XcmsFailure) { + return (XcmsFailure); + } + + /* Now check and return the appropriate value */ + if (pColor->spec.TekHVC.V == hvc_max.spec.TekHVC.V) { + /* When the value input is equal to the maximum value */ + /* merely return the chroma for that value. */ + pColor->spec.TekHVC.C = hvc_max.spec.TekHVC.C; + retval = _XcmsDIConvertColors(&myCCC, pColor, + &myCCC.pPerScrnInfo->screenWhitePt, 1, XcmsCIEXYZFormat); + } + + if (pColor->spec.TekHVC.V < hvc_max.spec.TekHVC.V) { + /* return the intersection of the perpindicular line through */ + /* the value and chroma given and the line from 0,0 and hvc_max. */ + Chroma = pColor->spec.TekHVC.C; + Value = pColor->spec.TekHVC.V; + pColor->spec.TekHVC.C = + (Value + (hvc_max.spec.TekHVC.C / hvc_max.spec.TekHVC.V * Chroma)) / + ((hvc_max.spec.TekHVC.V / hvc_max.spec.TekHVC.C) + + (hvc_max.spec.TekHVC.C / hvc_max.spec.TekHVC.V)); + if (pColor->spec.TekHVC.C >= hvc_max.spec.TekHVC.C) { + pColor->spec.TekHVC.C = hvc_max.spec.TekHVC.C; + pColor->spec.TekHVC.V = hvc_max.spec.TekHVC.V; + } else { + pColor->spec.TekHVC.V = pColor->spec.TekHVC.C * + hvc_max.spec.TekHVC.V / hvc_max.spec.TekHVC.C; + } + retval = _XcmsDIConvertColors(&myCCC, pColor, + &myCCC.pPerScrnInfo->screenWhitePt, 1, XcmsCIEXYZFormat); + + if (retval != XcmsFailure && pCompressed != NULL) { + *(pCompressed + i) = True; + } + return (retval); + } + + /* return the closest point on the upper part of the hue leaf. */ + /* must do a bisection here to compute the delta e. */ + nMaxCount = MAXBISECTCOUNT; + nI = nMaxCount / 2; + bestValue = Value = pColor->spec.TekHVC.V; + bestChroma = Chroma = pColor->spec.TekHVC.C; + saveDist = (XcmsFloat) XCMS_SQRT ((double) (((Chroma - hvc_max.spec.TekHVC.C) * + (Chroma - hvc_max.spec.TekHVC.C)) + + ((Value - hvc_max.spec.TekHVC.V) * + (Value - hvc_max.spec.TekHVC.V)))); + for (nCount = 0; nCount < nMaxCount; nCount++) { + nT = (XcmsFloat) nI / (XcmsFloat) nMaxCount; + pColor->spec.RGBi.red = rgb_max.red * (1.0 - nT) + nT; + pColor->spec.RGBi.green = rgb_max.green * (1.0 - nT) + nT; + pColor->spec.RGBi.blue = rgb_max.blue * (1.0 - nT) + nT; + pColor->format = XcmsRGBiFormat; + + /* Convert from RGBi to HVC */ + if (_XcmsConvertColorsWithWhitePt(&myCCC, pColor, + &myCCC.pPerScrnInfo->screenWhitePt, 1, XcmsTekHVCFormat, + (Bool *) NULL) + == XcmsFailure) { + return (XcmsFailure); + } + if (!_XcmsTekHVC_CheckModify(pColor)) { + return (XcmsFailure); + } + tmpDist = (XcmsFloat) XCMS_SQRT ((double) + (((Chroma - pColor->spec.TekHVC.C) * + (Chroma - pColor->spec.TekHVC.C)) + + ((Value - pColor->spec.TekHVC.V) * + (Value - pColor->spec.TekHVC.V)))); + nILast = nI; + if (tmpDist > saveDist) { + nI /= 2; + } else { + nI = (nMaxCount + nI) / 2; + saveDist = tmpDist; + bestValue = pColor->spec.TekHVC.V; + bestChroma = pColor->spec.TekHVC.C; + } + if (nI == nILast || nI == 0) { + break; + } + + } + + if (bestChroma >= hvc_max.spec.TekHVC.C) { + pColor->spec.TekHVC.C = hvc_max.spec.TekHVC.C; + pColor->spec.TekHVC.V = hvc_max.spec.TekHVC.V; + } else { + pColor->spec.TekHVC.C = bestChroma; + pColor->spec.TekHVC.V = bestValue; + } + if (!_XcmsTekHVC_CheckModify(pColor)) { + return (XcmsFailure); + } + retval = _XcmsDIConvertColors(&myCCC, pColor, + &myCCC.pPerScrnInfo->screenWhitePt, 1, XcmsCIEXYZFormat); + + if (retval != XcmsFailure && pCompressed != NULL) { + *(pCompressed + i) = True; + } + return(retval); + } +} diff --git a/src/xcms/HVCMnV.c b/src/xcms/HVCMnV.c new file mode 100644 index 00000000..f66e0e1c --- /dev/null +++ b/src/xcms/HVCMnV.c @@ -0,0 +1,167 @@ +/* $Xorg: HVCMnV.c,v 1.3 2000/08/17 19:44:37 cpqbld Exp $ */ + +/* + * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. + * All Rights Reserved + * + * This file is a component of an X Window System-specific implementation + * of Xcms based on the TekColor Color Management System. TekColor is a + * trademark of Tektronix, Inc. The term "TekHVC" designates a particular + * color space that is the subject of U.S. Patent No. 4,985,853 (equivalent + * foreign patents pending). Permission is hereby granted to use, copy, + * modify, sell, and otherwise distribute this software and its + * documentation for any purpose and without fee, provided that: + * + * 1. This copyright, permission, and disclaimer notice is reproduced in + * all copies of this software and any modification thereof and in + * supporting documentation; + * 2. Any color-handling application which displays TekHVC color + * cooordinates identifies these as TekHVC color coordinates in any + * interface that displays these coordinates and in any associated + * documentation; + * 3. The term "TekHVC" is always used, and is only used, in association + * with the mathematical derivations of the TekHVC Color Space, + * including those provided in this file and any equivalent pathways and + * mathematical derivations, regardless of digital (e.g., floating point + * or integer) representation. + * + * Tektronix makes no representation about the suitability of this software + * for any purpose. It is provided "as is" and with all faults. + * + * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, + * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX 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 THE PERFORMANCE OF THIS SOFTWARE. + * + * NAME + * TekHVCMnV.c + * + * DESCRIPTION + * Source for XcmsTekHVCQueryMinV gamut boundary querying routine. + * + */ + +#include "Xlibint.h" +#include "Xcmsint.h" + +/* + * DEFINES + */ +#define EPS 0.001 + +/* + * EXTERNS + */ +extern Status _XcmsTekHVCQueryMaxVCRGB(); +extern Status _XcmsTekHVC_CheckModify(); +extern XcmsColorSpace XcmsTekHVCColorSpace; + + +/************************************************************************ + * * + * PUBLIC ROUTINES * + * * + ************************************************************************/ + +/* + * NAME + * XcmsTekHVCQueryMinV - Compute minimum value for hue and chroma + * + * SYNOPSIS + */ +Status +XcmsTekHVCQueryMinV (ccc, hue, chroma, pColor_return) + XcmsCCC ccc; + XcmsFloat hue; + XcmsFloat chroma; + XcmsColor *pColor_return; + +/* + * DESCRIPTION + * Return the minimum value for a specific hue, and the + * corresponding chroma. The input color specification + * may be in any format, however output is in XcmsTekHVCFormat. + * + * Since this routine works with the value within + * pColor_return intermediate results may be returned + * even though it may be invalid. + * + * ASSUMPTIONS + * This routine assumes that the white point associated with + * the color specification is the Screen White Point. The + * Screen White Point will also be associated with the + * returned color specification. + * + * RETURNS + * XcmsFailure - Failure + * XcmsSuccess - Succeeded with no modifications + * + */ +{ + XcmsCCCRec myCCC; + XcmsColor tmp; + XcmsColor max_vc; + + /* + * Check Arguments + */ + if (ccc == NULL || pColor_return == NULL) { + return(XcmsFailure); + } + + /* + * Insure TekHVC installed + */ + if (XcmsAddColorSpace(&XcmsTekHVCColorSpace) == XcmsFailure) { + return(XcmsFailure); + } + + /* Use my own CCC */ + memcpy ((char *)&myCCC, (char *)ccc, sizeof(XcmsCCCRec)); + myCCC.clientWhitePt.format = XcmsUndefinedFormat;/* inherit screen white pt */ + myCCC.gamutCompProc = (XcmsCompressionProc)NULL;/* no gamut comp func */ + + tmp.spec.TekHVC.H = hue; + tmp.spec.TekHVC.V = 100.0; + tmp.spec.TekHVC.C = chroma; + tmp.pixel = pColor_return->pixel; + tmp.format = XcmsTekHVCFormat; + + + /* Check for a valid HVC */ + if (!_XcmsTekHVC_CheckModify (&tmp)) { + return(XcmsFailure); + } + + /* Step 1: compute the maximum value and chroma for this hue. */ + /* This copy may be overkill but it preserves the pixel etc. */ + memcpy((char *)&max_vc, (char *)&tmp, sizeof(XcmsColor)); + if (_XcmsTekHVCQueryMaxVCRGB (&myCCC, max_vc.spec.TekHVC.H, &max_vc, + (XcmsRGBi *)NULL) == XcmsFailure) { + return(XcmsFailure); + } + + /* Step 2: find the intersection with the maximum hvc and chroma line. */ + if (tmp.spec.TekHVC.C > max_vc.spec.TekHVC.C + EPS) { + /* If the chroma is to large then return maximum hvc. */ + tmp.spec.TekHVC.C = max_vc.spec.TekHVC.C; + tmp.spec.TekHVC.V = max_vc.spec.TekHVC.V; + } else { + tmp.spec.TekHVC.V = tmp.spec.TekHVC.C * + max_vc.spec.TekHVC.V / max_vc.spec.TekHVC.C; + if (tmp.spec.TekHVC.V > max_vc.spec.TekHVC.V) { + tmp.spec.TekHVC.V = max_vc.spec.TekHVC.V; + } else if (tmp.spec.TekHVC.V < 0.0) { + tmp.spec.TekHVC.V = tmp.spec.TekHVC.C = 0.0; + } + } + if (_XcmsTekHVC_CheckModify (&tmp)) { + memcpy ((char *) pColor_return, (char *) &tmp, sizeof (XcmsColor)); + return(XcmsSuccess); + } else { + return(XcmsFailure); + } +} diff --git a/src/xcms/HVCMxC.c b/src/xcms/HVCMxC.c new file mode 100644 index 00000000..e7e316fe --- /dev/null +++ b/src/xcms/HVCMxC.c @@ -0,0 +1,247 @@ +/* $Xorg: HVCMxC.c,v 1.3 2000/08/17 19:44:37 cpqbld Exp $ */ + +/* + * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. + * All Rights Reserved + * + * This file is a component of an X Window System-specific implementation + * of Xcms based on the TekColor Color Management System. TekColor is a + * trademark of Tektronix, Inc. The term "TekHVC" designates a particular + * color space that is the subject of U.S. Patent No. 4,985,853 (equivalent + * foreign patents pending). Permission is hereby granted to use, copy, + * modify, sell, and otherwise distribute this software and its + * documentation for any purpose and without fee, provided that: + * + * 1. This copyright, permission, and disclaimer notice is reproduced in + * all copies of this software and any modification thereof and in + * supporting documentation; + * 2. Any color-handling application which displays TekHVC color + * cooordinates identifies these as TekHVC color coordinates in any + * interface that displays these coordinates and in any associated + * documentation; + * 3. The term "TekHVC" is always used, and is only used, in association + * with the mathematical derivations of the TekHVC Color Space, + * including those provided in this file and any equivalent pathways and + * mathematical derivations, regardless of digital (e.g., floating point + * or integer) representation. + * + * Tektronix makes no representation about the suitability of this software + * for any purpose. It is provided "as is" and with all faults. + * + * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, + * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX 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 THE PERFORMANCE OF THIS SOFTWARE. + * + * NAME + * TekHVCMxC.c + * + * DESCRIPTION + * Source for the XcmsTekHVCQueryMaxC() gamut boudary + * querying routine. + * + */ + +#include "Xlibint.h" +#include "Xcmsint.h" +#include <math.h> + +/* + * DEFINES + */ +#define MAXBISECTCOUNT 100 +#define EPS 0.001 + +/* + * EXTERNS + */ +extern Status _XcmsTekHVCQueryMaxVCRGB(); +extern int _XcmsTekHVC_CheckModify(); +extern XcmsColorSpace XcmsTekHVCColorSpace; + + + +/************************************************************************ + * * + * PUBLIC ROUTINES * + * * + ************************************************************************/ + +/* + * NAME + * XcmsTekHVCQueryMaxC - Compute the maximum chroma for a hue and value + * + * SYNOPSIS + */ +Status +XcmsTekHVCQueryMaxC(ccc, hue, value, pColor_return) + XcmsCCC ccc; + XcmsFloat hue; + XcmsFloat value; + XcmsColor *pColor_return; +/* + * DESCRIPTION + * Return the maximum chroma for a specific hue and value. + * The returned format is in XcmsTekHVCFormat. + * + * + * ASSUMPTIONS + * This routine assumes that the white point associated with + * the color specification is the Screen White Point. The + * Screen White Point will also be associated with the + * returned color specification. + * + * RETURNS + * XcmsFailure - Failure + * XcmsSuccess - Succeeded + * + */ +{ + XcmsCCCRec myCCC; + XcmsColor tmp; + XcmsColor max_vc; + XcmsRGBi rgb_saved; + int nCount, nMaxCount; + XcmsFloat nValue, savedValue, lastValue, lastChroma, prevValue; + XcmsFloat maxDist, nT, rFactor; + XcmsFloat ftmp1, ftmp2; + + /* + * Check Arguments + */ + if (ccc == NULL || pColor_return == NULL) { + return(XcmsFailure); + } + + /* + * Insure TekHVC installed + */ + if (XcmsAddColorSpace(&XcmsTekHVCColorSpace) == XcmsFailure) { + return(XcmsFailure); + } + + /* Use my own CCC */ + memcpy ((char *)&myCCC, (char *)ccc, sizeof(XcmsCCCRec)); + myCCC.clientWhitePt.format = XcmsUndefinedFormat; /* inherit screen white Pt */ + myCCC.gamutCompProc = (XcmsCompressionProc)NULL;/* no gamut comp func */ + + tmp.spec.TekHVC.H = hue; + tmp.spec.TekHVC.V = value; + tmp.spec.TekHVC.C = 100.0; + tmp.pixel = pColor_return->pixel; + tmp.format = XcmsTekHVCFormat; + + /* check to make sure we have a valid TekHVC number */ + if (!_XcmsTekHVC_CheckModify(&tmp)) { + return(XcmsFailure); + } + + /* Step 1: compute the maximum value and chroma for this hue. */ + memcpy((char *)&max_vc, (char *)&tmp, sizeof(XcmsColor)); + if (_XcmsTekHVCQueryMaxVCRGB(&myCCC, hue, &max_vc, &rgb_saved) + == XcmsFailure) { + return(XcmsFailure); + } + + /* Step 2: If the value is less than the value for the maximum */ + /* value, chroma point then the chroma is on the line */ + /* from max_vc to 0,0. */ + if (value <= max_vc.spec.TekHVC.V) { + tmp.spec.TekHVC.C = value + * max_vc.spec.TekHVC.C / max_vc.spec.TekHVC.V; + if (_XcmsTekHVC_CheckModify (&tmp)) { + memcpy((char *)pColor_return, (char *)&tmp, sizeof(XcmsColor)); + return(XcmsSuccess); + } else { + return(XcmsFailure); + } + } else { + /* must do a bisection here to compute the maximum chroma */ + /* save the structure input so that any elements that */ + /* are not touched are recopied later in the routine. */ + nValue = savedValue = value; + lastValue = -1.0; + nMaxCount = MAXBISECTCOUNT; + maxDist = 100.0 - max_vc.spec.TekHVC.V; + rFactor = 1.0; + + for (nCount = 0; nCount < nMaxCount; nCount++) { + prevValue = lastValue; + lastValue = tmp.spec.TekHVC.V; + lastChroma = tmp.spec.TekHVC.C; + nT = (nValue - max_vc.spec.TekHVC.V) / maxDist * rFactor; + tmp.spec.RGBi.red = rgb_saved.red * (1.0 - nT) + nT; + tmp.spec.RGBi.green = rgb_saved.green * (1.0 - nT) + nT; + tmp.spec.RGBi.blue = rgb_saved.blue * (1.0 - nT) + nT; + tmp.format = XcmsRGBiFormat; + + /* convert from RGB to HVC */ + if (_XcmsConvertColorsWithWhitePt(&myCCC, &tmp, + &myCCC.pPerScrnInfo->screenWhitePt, 1, XcmsTekHVCFormat, + (Bool *) NULL) == XcmsFailure) { + return(XcmsFailure); + } + + /* Now check the return against what is expected */ + if (tmp.spec.TekHVC.V <= savedValue + EPS && + tmp.spec.TekHVC.V >= savedValue - EPS) { + /* make sure to return the input hue */ + tmp.spec.TekHVC.H = hue; + if (_XcmsTekHVC_CheckModify (&tmp)) { + memcpy((char *)pColor_return, (char *)&tmp, sizeof(XcmsColor)); + return(XcmsSuccess); + } else { + return(XcmsFailure); + } + } + nValue += savedValue - tmp.spec.TekHVC.V; + if (nValue < max_vc.spec.TekHVC.V) { + nValue = max_vc.spec.TekHVC.V; + rFactor *= 0.5; /* selective relaxation employed */ + } else if (nValue > 100.0) { + /* make sure to return the input hue */ + tmp.spec.TekHVC.H = hue; + /* avoid using fabs */ + ftmp1 = lastValue - savedValue; + if (ftmp1 < 0.0) + ftmp1 = -ftmp1; + ftmp2 = tmp.spec.TekHVC.V - savedValue; + if (ftmp2 < 0.0) + ftmp2 = -ftmp2; + if (ftmp1 < ftmp2) { + tmp.spec.TekHVC.V = lastValue; + tmp.spec.TekHVC.C = lastChroma; + } + if (_XcmsTekHVC_CheckModify (&tmp)) { + memcpy((char *)pColor_return, (char *)&tmp, sizeof(XcmsColor)); + return(XcmsSuccess); + } else { + return(XcmsFailure); + } + } else if (tmp.spec.TekHVC.V <= prevValue + EPS && + tmp.spec.TekHVC.V >= prevValue - EPS) { + rFactor *= 0.5; /* selective relaxation employed */ + } + } + if (nCount >= nMaxCount) { + /* avoid using fabs */ + ftmp1 = lastValue - savedValue; + if (ftmp1 < 0.0) + ftmp1 = -ftmp1; + ftmp2 = tmp.spec.TekHVC.V - savedValue; + if (ftmp2 < 0.0) + ftmp2 = -ftmp2; + if (ftmp1 < ftmp2) { + tmp.spec.TekHVC.V = lastValue; + tmp.spec.TekHVC.C = lastChroma; + } + } + } + /* make sure to return the input hue */ + tmp.spec.TekHVC.H = hue; + memcpy((char *)pColor_return, (char *)&tmp, sizeof(XcmsColor)); + return(XcmsSuccess); +} diff --git a/src/xcms/HVCMxV.c b/src/xcms/HVCMxV.c new file mode 100644 index 00000000..b1e70094 --- /dev/null +++ b/src/xcms/HVCMxV.c @@ -0,0 +1,250 @@ +/* $Xorg: HVCMxV.c,v 1.3 2000/08/17 19:44:37 cpqbld Exp $ */ + +/* + * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. + * All Rights Reserved + * + * This file is a component of an X Window System-specific implementation + * of Xcms based on the TekColor Color Management System. TekColor is a + * trademark of Tektronix, Inc. The term "TekHVC" designates a particular + * color space that is the subject of U.S. Patent No. 4,985,853 (equivalent + * foreign patents pending). Permission is hereby granted to use, copy, + * modify, sell, and otherwise distribute this software and its + * documentation for any purpose and without fee, provided that: + * + * 1. This copyright, permission, and disclaimer notice is reproduced in + * all copies of this software and any modification thereof and in + * supporting documentation; + * 2. Any color-handling application which displays TekHVC color + * cooordinates identifies these as TekHVC color coordinates in any + * interface that displays these coordinates and in any associated + * documentation; + * 3. The term "TekHVC" is always used, and is only used, in association + * with the mathematical derivations of the TekHVC Color Space, + * including those provided in this file and any equivalent pathways and + * mathematical derivations, regardless of digital (e.g., floating point + * or integer) representation. + * + * Tektronix makes no representation about the suitability of this software + * for any purpose. It is provided "as is" and with all faults. + * + * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, + * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX 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 THE PERFORMANCE OF THIS SOFTWARE. + * + * NAME + * TekHVCMxV.c + * + * DESCRIPTION + * Source for the XcmsTekHVCQueryMaxV() gamut boundary + * querying routine. + * + */ + +#include "Xlibint.h" +#include "Xcmsint.h" +#include <math.h> + +/* + * DEFINES + */ +#define MAXBISECTCOUNT 100 +#define EPS 0.001 + +/* + * EXTERNS + */ +extern Status _XcmsTekHVCQueryMaxVCRGB(); +extern int _XcmsTekHVC_CheckModify(); +extern XcmsColorSpace XcmsTekHVCColorSpace; + + +/************************************************************************ + * * + * PUBLIC ROUTINES * + * * + ************************************************************************/ + +/* + * NAME + * XcmsTekHVCQueryMaxV - Compute maximum value for a hue and chroma + * + * SYNOPSIS + */ +Status +XcmsTekHVCQueryMaxV(ccc, hue, chroma, pColor_return) + XcmsCCC ccc; + XcmsFloat hue; + XcmsFloat chroma; + XcmsColor *pColor_return; +/* + * DESCRIPTION + * Return the maximum value for a specified hue and chroma. + * + * ASSUMPTIONS + * This routine assumes that the white point associated with + * the color specification is the Screen White Point. The + * Screen White Point will also be associated with the + * returned color specification. + * + * RETURNS + * XcmsFailure - Failure + * XcmsSuccess - Succeeded with no modifications + * + */ +{ + XcmsCCCRec myCCC; + XcmsColor tmp; + XcmsColor max_vc; + XcmsRGBi rgb_saved; + int nCount, nMaxCount; + XcmsFloat nT, nChroma, savedChroma, lastValue, lastChroma, prevChroma; + XcmsFloat rFactor; + XcmsFloat ftmp1, ftmp2; + + /* + * Check Arguments + */ + if (ccc == NULL || pColor_return == NULL) { + return(XcmsFailure); + } + + /* + * Insure TekHVC installed + */ + if (XcmsAddColorSpace(&XcmsTekHVCColorSpace) == XcmsFailure) { + return(XcmsFailure); + } + + /* setup the CCC to use for the conversions. */ + memcpy ((char *) &myCCC, (char *) ccc, sizeof(XcmsCCCRec)); + myCCC.clientWhitePt.format = XcmsUndefinedFormat; + myCCC.gamutCompProc = (XcmsCompressionProc) NULL; + + tmp.spec.TekHVC.H = hue; + tmp.spec.TekHVC.V = 0.0; + tmp.spec.TekHVC.C = chroma; + tmp.pixel = pColor_return->pixel; + tmp.format = XcmsTekHVCFormat; + + if (!_XcmsTekHVC_CheckModify (&tmp)) { + return(XcmsFailure); + } + + /* Step 1: compute the maximum value and chroma for this hue. */ + /* This copy may be overkill but it preserves the pixel etc. */ + memcpy((char *)&max_vc, (char *)&tmp, sizeof(XcmsColor)); + hue = max_vc.spec.TekHVC.H; + if (_XcmsTekHVCQueryMaxVCRGB(&myCCC, max_vc.spec.TekHVC.H, &max_vc, &rgb_saved) + == XcmsFailure) { + return(XcmsFailure); + } + + if (max_vc.spec.TekHVC.C < tmp.spec.TekHVC.C) { + /* + * If the chroma is greater than the chroma for the + * maximum value/chroma point then the value is the + * the value for the maximum value, chroma point. + * This is an error but it I return the best approximation I can. + * Thus the inconsistency. + */ + tmp.spec.TekHVC.C = max_vc.spec.TekHVC.C; + tmp.spec.TekHVC.V = max_vc.spec.TekHVC.V; + memcpy ((char *) pColor_return, (char *) &tmp, sizeof (XcmsColor)); + return(XcmsSuccess); + } else if (max_vc.spec.TekHVC.C == tmp.spec.TekHVC.C) { + /* + * If the chroma is equal to the chroma for the + * maximum value/chroma point then the value is the + * the value for the maximum value, chroma point. + */ + tmp.spec.TekHVC.V = max_vc.spec.TekHVC.V; + memcpy ((char *) pColor_return, (char *) &tmp, sizeof (XcmsColor)); + return(XcmsSuccess); + } else { + /* must do a bisection here to compute the maximum value */ + /* save the structure input so that any elements that */ + /* are not touched are recopied later in the routine. */ + nChroma = savedChroma = tmp.spec.TekHVC.C; + tmp.spec.TekHVC.C = max_vc.spec.TekHVC.C; + tmp.spec.TekHVC.V = max_vc.spec.TekHVC.V; + lastChroma = -1.0; + nMaxCount = MAXBISECTCOUNT; + rFactor = 1.0; + + for (nCount = 0; nCount < nMaxCount; nCount++) { + prevChroma = lastChroma; + lastValue = tmp.spec.TekHVC.V; + lastChroma = tmp.spec.TekHVC.C; + nT = (1.0 - (nChroma / max_vc.spec.TekHVC.C)) * rFactor; + tmp.spec.RGBi.red = rgb_saved.red * (1.0 - nT) + nT; + tmp.spec.RGBi.green = rgb_saved.green * (1.0 - nT) + nT; + tmp.spec.RGBi.blue = rgb_saved.blue * (1.0 - nT) + nT; + tmp.format = XcmsRGBiFormat; + + /* convert from RGB to HVC */ + if (_XcmsConvertColorsWithWhitePt(&myCCC, &tmp, + &myCCC.pPerScrnInfo->screenWhitePt, 1, XcmsTekHVCFormat, + (Bool *) NULL) == XcmsFailure) { + return(XcmsFailure); + } + + /* Now check the return against what is expected */ + if (tmp.spec.TekHVC.C <= savedChroma + EPS && + tmp.spec.TekHVC.C >= savedChroma - EPS) { + tmp.spec.TekHVC.H = hue; /* use the saved hue */ + memcpy ((char *) pColor_return, (char *) &tmp, sizeof (XcmsColor)); + return(XcmsSuccess); + } + nChroma += savedChroma - tmp.spec.TekHVC.C; + if (nChroma > max_vc.spec.TekHVC.C) { + nChroma = max_vc.spec.TekHVC.C; + rFactor *= 0.5; /* selective relaxation employed */ + } else if (nChroma < 0.0) { + /* avoid using fabs */ + ftmp1 = lastChroma - savedChroma; + if (ftmp1 < 0.0) + ftmp1 = -ftmp1; + ftmp2 = tmp.spec.TekHVC.C - savedChroma; + if (ftmp2 < 0.0) + ftmp2 = -ftmp2; + if (ftmp1 < ftmp2) { + tmp.spec.TekHVC.V = lastValue; + tmp.spec.TekHVC.C = lastChroma; + } + /* make sure to return the input hue */ + tmp.spec.TekHVC.H = hue; + if (!_XcmsTekHVC_CheckModify(&tmp)) { + return(XcmsFailure); + } + memcpy ((char *) pColor_return, (char *) &tmp, sizeof (XcmsColor)); + return(XcmsSuccess); + } else if (tmp.spec.TekHVC.C <= prevChroma + EPS && + tmp.spec.TekHVC.C >= prevChroma - EPS) { + rFactor *= 0.5; /* selective relaxation employed */ + } + } + if (nCount >= nMaxCount) { + /* avoid using fabs */ + ftmp1 = lastChroma - savedChroma; + if (ftmp1 < 0.0) + ftmp1 = -ftmp1; + ftmp2 = tmp.spec.TekHVC.C - savedChroma; + if (ftmp2 < 0.0) + ftmp2 = -ftmp2; + if (ftmp1 < ftmp2) { + tmp.spec.TekHVC.V = lastValue; + tmp.spec.TekHVC.C = lastChroma; + } + } + } + + /* make sure to return the input hue */ + tmp.spec.TekHVC.H = hue; + memcpy ((char *) pColor_return, (char *) &tmp, sizeof (XcmsColor)); + return(XcmsSuccess); +} diff --git a/src/xcms/HVCMxVC.c b/src/xcms/HVCMxVC.c new file mode 100644 index 00000000..7c8ec7d0 --- /dev/null +++ b/src/xcms/HVCMxVC.c @@ -0,0 +1,244 @@ +/* $Xorg: HVCMxVC.c,v 1.3 2000/08/17 19:44:37 cpqbld Exp $ */ + +/* + * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. + * All Rights Reserved + * + * This file is a component of an X Window System-specific implementation + * of Xcms based on the TekColor Color Management System. TekColor is a + * trademark of Tektronix, Inc. The term "TekHVC" designates a particular + * color space that is the subject of U.S. Patent No. 4,985,853 (equivalent + * foreign patents pending). Permission is hereby granted to use, copy, + * modify, sell, and otherwise distribute this software and its + * documentation for any purpose and without fee, provided that: + * + * 1. This copyright, permission, and disclaimer notice is reproduced in + * all copies of this software and any modification thereof and in + * supporting documentation; + * 2. Any color-handling application which displays TekHVC color + * cooordinates identifies these as TekHVC color coordinates in any + * interface that displays these coordinates and in any associated + * documentation; + * 3. The term "TekHVC" is always used, and is only used, in association + * with the mathematical derivations of the TekHVC Color Space, + * including those provided in this file and any equivalent pathways and + * mathematical derivations, regardless of digital (e.g., floating point + * or integer) representation. + * + * Tektronix makes no representation about the suitability of this software + * for any purpose. It is provided "as is" and with all faults. + * + * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, + * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX 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 THE PERFORMANCE OF THIS SOFTWARE. + * + * NAME + * TekHVCMxVC.c + * + * DESCRIPTION + * Source for the XcmsTekHVCQueryMaxVC() gamut boundary + * querying routine. + * + */ + +#include "Xlibint.h" +#include "Xcmsint.h" + +/* + * DEFINES + */ +#define MIN(x,y) ((x) > (y) ? (y) : (x)) +#define MIN3(x,y,z) ((x) > (MIN((y), (z))) ? (MIN((y), (z))) : (x)) +#define MAX(x,y) ((x) > (y) ? (x) : (y)) +#define MAX3(x,y,z) ((x) > (MAX((y), (z))) ? (x) : (MAX((y), (z)))) +#define START_V 40.0 +#define START_C 120.0 + +/* + * EXTERNS + */ +extern Status _XcmsTekHVC_CheckModify(); +extern Status _XcmsConvertColorsWithWhitePt(); +extern XcmsColorSpace XcmsTekHVCColorSpace; + +/* + * FORWARD DECLARATIONS + */ +Status _XcmsTekHVCQueryMaxVCRGB(); + + +/************************************************************************ + * * + * API PRIVATE ROUTINES * + * * + ************************************************************************/ + +/* + * NAME + * _XcmsTekHVCQueryMaxVCRGB - Compute maximum value/chroma. + * + * SYNOPSIS + */ +Status +_XcmsTekHVCQueryMaxVCRGB(ccc, hue, pColor_return, pRGB_return) + XcmsCCC ccc; + XcmsFloat hue; + XcmsColor *pColor_return; + XcmsRGBi *pRGB_return; + +/* + * DESCRIPTION + * Return the maximum chroma for a specified hue, and the + * corresponding value. This is computed by a binary search of + * all possible chromas. An assumption is made that there are + * no local maxima. Use the unrounded Max Chroma because + * the difference check can be small. + * + * NOTE: No local CCC is used because this is a private + * routine and all routines that call it are expected + * to behave properly, i.e. send a local CCC with + * no white adjust function and no gamut compression + * function. + * + * This routine only accepts hue as input and outputs + * HVC's and RGBi's. + * + * RETURNS + * XcmsFailure - Failure + * XCMS_SUCCUSS - Succeeded + * + */ +{ + XcmsFloat nSmall, nLarge; + XcmsColor tmp; + + tmp.format = XcmsTekHVCFormat; + tmp.spec.TekHVC.H = hue; + /* Use some unreachable color on the given hue */ + tmp.spec.TekHVC.V = START_V; + tmp.spec.TekHVC.C = START_C; + + + /* + * Convert from HVC to RGB + * + * Note that the CIEXYZ to RGBi conversion routine must stuff the + * out of bounds RGBi values in tmp when the ccc->gamutCompProc + * is NULL. + */ + if ((_XcmsConvertColorsWithWhitePt(ccc, &tmp, + &ccc->pPerScrnInfo->screenWhitePt, 1, XcmsRGBiFormat, (Bool *) NULL) + == XcmsFailure) && tmp.format != XcmsRGBiFormat) { + return (XcmsFailure); + } + + /* Now pick the smallest RGB */ + nSmall = MIN3(tmp.spec.RGBi.red, + tmp.spec.RGBi.green, + tmp.spec.RGBi.blue); + /* Make the smallest RGB equal to zero */ + tmp.spec.RGBi.red -= nSmall; + tmp.spec.RGBi.green -= nSmall; + tmp.spec.RGBi.blue -= nSmall; + + /* Now pick the largest RGB */ + nLarge = MAX3(tmp.spec.RGBi.red, + tmp.spec.RGBi.green, + tmp.spec.RGBi.blue); + /* Scale the RGB values based on the largest one */ + tmp.spec.RGBi.red /= nLarge; + tmp.spec.RGBi.green /= nLarge; + tmp.spec.RGBi.blue /= nLarge; + tmp.format = XcmsRGBiFormat; + + /* If the calling routine wants RGB value give them the ones used. */ + if (pRGB_return) { + pRGB_return->red = tmp.spec.RGBi.red; + pRGB_return->green = tmp.spec.RGBi.green; + pRGB_return->blue = tmp.spec.RGBi.blue; + } + + /* Convert from RGBi to HVC */ + if (_XcmsConvertColorsWithWhitePt(ccc, &tmp, + &ccc->pPerScrnInfo->screenWhitePt, 1, XcmsTekHVCFormat, (Bool *) NULL) + == XcmsFailure) { + return (XcmsFailure); + } + + /* make sure to return the input hue */ + tmp.spec.TekHVC.H = hue; + memcpy((char *)pColor_return, (char *)&tmp, sizeof(XcmsColor)); + return (XcmsSuccess); +} + + +/************************************************************************ + * * + * PUBLIC ROUTINES * + * * + ************************************************************************/ + +/* + * NAME + * XcmsTekHVCQueryMaxVC - Compute maximum value and chroma. + * + * SYNOPSIS + */ +Status +XcmsTekHVCQueryMaxVC (ccc, hue, pColor_return) + XcmsCCC ccc; + XcmsFloat hue; + XcmsColor *pColor_return; + +/* + * DESCRIPTION + * Return the maximum chroma for the specified hue, and the + * corresponding value. + * + * ASSUMPTIONS + * This routine assumes that the white point associated with + * the color specification is the Screen White Point. The + * Screen White Point will also be associated with the + * returned color specification. + * + * RETURNS + * XcmsFailure - Failure + * XcmsSuccess - Succeeded + * + */ +{ + XcmsCCCRec myCCC; + + /* + * Check Arguments + */ + if (ccc == NULL || pColor_return == NULL) { + return(XcmsFailure); + } + + /* + * Insure TekHVC installed + */ + if (XcmsAddColorSpace(&XcmsTekHVCColorSpace) == XcmsFailure) { + return(XcmsFailure); + } + + /* Use my own CCC */ + memcpy ((char *)&myCCC, (char *)ccc, sizeof(XcmsCCCRec)); + myCCC.clientWhitePt.format = XcmsUndefinedFormat; + myCCC.gamutCompProc = (XcmsCompressionProc)NULL; + + while (hue < 0.0) { + hue += 360.0; + } + while (hue >= 360.0) { + hue -= 360.0; + } + + return(_XcmsTekHVCQueryMaxVCRGB (&myCCC, hue, pColor_return, + (XcmsRGBi *)NULL)); +} diff --git a/src/xcms/HVCMxVs.c b/src/xcms/HVCMxVs.c new file mode 100644 index 00000000..33f84b61 --- /dev/null +++ b/src/xcms/HVCMxVs.c @@ -0,0 +1,166 @@ +/* $Xorg: HVCMxVs.c,v 1.3 2000/08/17 19:44:37 cpqbld Exp $ */ + +/* + * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. + * All Rights Reserved + * + * This file is a component of an X Window System-specific implementation + * of Xcms based on the TekColor Color Management System. TekColor is a + * trademark of Tektronix, Inc. The term "TekHVC" designates a particular + * color space that is the subject of U.S. Patent No. 4,985,853 (equivalent + * foreign patents pending). Permission is hereby granted to use, copy, + * modify, sell, and otherwise distribute this software and its + * documentation for any purpose and without fee, provided that: + * + * 1. This copyright, permission, and disclaimer notice is reproduced in + * all copies of this software and any modification thereof and in + * supporting documentation; + * 2. Any color-handling application which displays TekHVC color + * cooordinates identifies these as TekHVC color coordinates in any + * interface that displays these coordinates and in any associated + * documentation; + * 3. The term "TekHVC" is always used, and is only used, in association + * with the mathematical derivations of the TekHVC Color Space, + * including those provided in this file and any equivalent pathways and + * mathematical derivations, regardless of digital (e.g., floating point + * or integer) representation. + * + * Tektronix makes no representation about the suitability of this software + * for any purpose. It is provided "as is" and with all faults. + * + * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, + * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX 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 THE PERFORMANCE OF THIS SOFTWARE. + * + * NAME + * TekHVCMxVs.c + * + * DESCRIPTION + * Source for the XcmsTekHVCQueryMaxVSamples() gamut boundary + * querying routine. + */ + +#include "Xlibint.h" +#include "Xcmsint.h" + +/* + * EXTERNS + */ +extern Status _XcmsTekHVCQueryMaxVCRGB(); +extern Status _XcmsTekHVC_CheckModify(); +extern XcmsColorSpace XcmsTekHVCColorSpace; + + + +/************************************************************************ + * * + * PUBLIC ROUTINES * + * * + ************************************************************************/ + +/* + * NAME + * XcmsTekHVCQueryMaxVSamples - Compute a set of value/chroma + * pairs. + * + * SYNOPSIS + */ +Status +XcmsTekHVCQueryMaxVSamples(ccc, hue, pColor_in_out, nSamples) + XcmsCCC ccc; + XcmsFloat hue; + XcmsColor *pColor_in_out; + unsigned int nSamples; + +/* + * DESCRIPTION + * Return a set of values and chromas for the input Hue. + * This routine will take any color as input. + * It returns TekHVC colors. + * + * Since this routine works with the value within + * pColor_in_out intermediate results may be returned + * even though it may be invalid. + * + * ASSUMPTIONS + * This routine assumes that the white point associated with + * the color specification is the Screen White Point. The + * Screen White Point will also be associated with the + * returned color specification. + * + * RETURNS + * XcmsFailure - Failure + * XcmsSuccess - Succeeded + * + */ +{ + XcmsCCCRec myCCC; + XcmsColor *pHVC; + XcmsRGBi rgb_saved; + unsigned short nI; + XcmsFloat nT; + + /* + * Check Arguments + */ + if (ccc == NULL || pColor_in_out == NULL || nSamples == 0) { + return(XcmsFailure); + } + + /* + * Insure TekHVC installed + */ + if (XcmsAddColorSpace(&XcmsTekHVCColorSpace) == XcmsFailure) { + return(XcmsFailure); + } + + /* setup the CCC to use for the conversions. */ + memcpy ((char *) &myCCC, (char *) ccc, sizeof(XcmsCCCRec)); + myCCC.clientWhitePt.format = XcmsUndefinedFormat; + myCCC.gamutCompProc = (XcmsCompressionProc) NULL; + + /* Step 1: compute the maximum value and chroma for this hue. */ + + + /* save the Hue for use later. */ + while (hue < 0.0) { + hue += 360.0; + } + while (hue > 360.0) { + hue -= 360.0; + } + pColor_in_out->spec.TekHVC.H = hue; + pColor_in_out->format = XcmsTekHVCFormat; + + /* Get the maximum value and chroma point for this hue */ + if (_XcmsTekHVCQueryMaxVCRGB(&myCCC, pColor_in_out->spec.TekHVC.H, + pColor_in_out, (XcmsRGBi *)&rgb_saved) == XcmsFailure) { + return (XcmsFailure); + } + + /* Step 2: Convert each of the RGBi's to HVC's */ + pHVC = pColor_in_out; + for (nI = 0; nI < nSamples; nI++, pHVC++) { + nT = (XcmsFloat) nI / (XcmsFloat) nSamples; + pHVC->spec.RGBi.red = rgb_saved.red * (1.0 - nT) + nT; + pHVC->spec.RGBi.green = rgb_saved.green * (1.0 - nT) + nT; + pHVC->spec.RGBi.blue = rgb_saved.blue * (1.0 - nT) + nT; + pHVC->format = XcmsRGBiFormat; + pHVC->pixel = pColor_in_out->pixel; + /* convert from RGB to HVC */ + if (_XcmsConvertColorsWithWhitePt(&myCCC, pHVC, + &myCCC.pPerScrnInfo->screenWhitePt, 1, XcmsTekHVCFormat, + (Bool *) NULL) == XcmsFailure) { + return(XcmsFailure); + } + + /* make sure to return the input hue */ + pHVC->spec.TekHVC.H = hue; + } + + return(XcmsSuccess); +} diff --git a/src/xcms/HVCWpAj.c b/src/xcms/HVCWpAj.c new file mode 100644 index 00000000..76e64c05 --- /dev/null +++ b/src/xcms/HVCWpAj.c @@ -0,0 +1,118 @@ +/* $Xorg: HVCWpAj.c,v 1.3 2000/08/17 19:44:37 cpqbld Exp $ */ + +/* + * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. + * All Rights Reserved + * + * This file is a component of an X Window System-specific implementation + * of Xcms based on the TekColor Color Management System. TekColor is a + * trademark of Tektronix, Inc. The term "TekHVC" designates a particular + * color space that is the subject of U.S. Patent No. 4,985,853 (equivalent + * foreign patents pending). Permission is hereby granted to use, copy, + * modify, sell, and otherwise distribute this software and its + * documentation for any purpose and without fee, provided that: + * + * 1. This copyright, permission, and disclaimer notice is reproduced in + * all copies of this software and any modification thereof and in + * supporting documentation; + * 2. Any color-handling application which displays TekHVC color + * cooordinates identifies these as TekHVC color coordinates in any + * interface that displays these coordinates and in any associated + * documentation; + * 3. The term "TekHVC" is always used, and is only used, in association + * with the mathematical derivations of the TekHVC Color Space, + * including those provided in this file and any equivalent pathways and + * mathematical derivations, regardless of digital (e.g., floating point + * or integer) representation. + * + * Tektronix makes no representation about the suitability of this software + * for any purpose. It is provided "as is" and with all faults. + * + * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, + * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX 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 THE PERFORMANCE OF THIS SOFTWARE. + * + * DESCRIPTION + * TekHVCWpAj.c + * + * DESCRIPTION + * This file contains routine(s) that support white point + * adjustment of color specifications in the TekHVC color + * space. + */ + +#include "Xlibint.h" +#include "Xcmsint.h" + +/* + * EXTERNS + */ +extern Status _XcmsConvertColorsWithWhitePt(); +extern XcmsColorSpace XcmsTekHVCColorSpace; + + +/************************************************************************ + * * + * PUBLIC ROUTINES * + * * + ************************************************************************/ + +/* + * NAME + * XcmsTekHVCWhiteShiftColors + * + * SYNOPSIS + */ +Status +XcmsTekHVCWhiteShiftColors(ccc, pWhitePtFrom, pWhitePtTo, destSpecFmt, + pColors_in_out, nColors, pCompressed) + XcmsCCC ccc; + XcmsColor *pWhitePtFrom; + XcmsColor *pWhitePtTo; + XcmsColorFormat destSpecFmt; + XcmsColor *pColors_in_out; + unsigned int nColors; + Bool *pCompressed; +/* + * DESCRIPTION + * Convert color specifications in an array of XcmsColor structures + * for differences in white points. + * + * RETURNS + * XcmsFailure if failed, + * XcmsSuccess if succeeded without gamut compression, + * XcmsSuccessWithCompression if succeeded with + * gamut compression. + */ +{ + if (pWhitePtFrom == NULL || pWhitePtTo == NULL || pColors_in_out == NULL) { + return(XcmsFailure); + } + + /* + * Insure TekHVC installed + */ + if (XcmsAddColorSpace(&XcmsTekHVCColorSpace) == XcmsFailure) { + return(XcmsFailure); + } + + /* + * Convert to TekHVC using pWhitePtFrom + * We can ignore return value for compression because we are converting + * to XcmsTekHVCFormat which is device-independent, not device-dependent. + */ + if (_XcmsConvertColorsWithWhitePt(ccc, pColors_in_out, pWhitePtFrom, + nColors, XcmsTekHVCFormat, pCompressed) == XcmsFailure) { + return(XcmsFailure); + } + + /* + * Convert from TekHVC to destSpecFmt using pWhitePtTo + */ + return(_XcmsConvertColorsWithWhitePt(ccc, pColors_in_out, pWhitePtTo, + nColors, destSpecFmt, pCompressed)); +} diff --git a/src/xcms/IdOfPr.c b/src/xcms/IdOfPr.c new file mode 100644 index 00000000..d84986eb --- /dev/null +++ b/src/xcms/IdOfPr.c @@ -0,0 +1,111 @@ +/* $Xorg: IdOfPr.c,v 1.3 2000/08/17 19:44:38 cpqbld Exp $ */ + +/* + * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. + * All Rights Reserved + * + * This file is a component of an X Window System-specific implementation + * of Xcms based on the TekColor Color Management System. Permission is + * hereby granted to use, copy, modify, sell, and otherwise distribute this + * software and its documentation for any purpose and without fee, provided + * that this copyright, permission, and disclaimer notice is reproduced in + * all copies of this software and in supporting documentation. TekColor + * is a trademark of Tektronix, Inc. + * + * Tektronix makes no representation about the suitability of this software + * for any purpose. It is provided "as is" and with all faults. + * + * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, + * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX 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 THE PERFORMANCE OF THIS SOFTWARE. + * + * + * NAME + * XcmsIdOfPr.c + * + * DESCRIPTION + * Source for XcmsFormatOfPrefix() + * + * + */ + +#include "Xlibint.h" +#include "Xcmsint.h" + +/* + * EXTERNS + */ +extern XcmsColorSpace **_XcmsDIColorSpaces; +extern XcmsColorSpace **_XcmsDDColorSpaces; +void _XcmsCopyISOLatin1Lowered(); + + +/* + * NAME + * XcmsFormatOfPrefix + * + * SYNOPSIS + */ +XcmsColorFormat +XcmsFormatOfPrefix(prefix) + char *prefix; +/* + * DESCRIPTION + * Returns the Color Space ID for the specified prefix + * if the color space is found in the Color Conversion + * Context. + * + * RETURNS + * Color Space ID if found; zero otherwise. + */ +{ + XcmsColorSpace **papColorSpaces; + char string_buf[64]; + char *string_lowered; + int len; + + /* + * While copying prefix to string_lowered, convert to lowercase + */ + if ((len = strlen(prefix)) >= sizeof(string_buf)) { + string_lowered = (char *) Xmalloc(len+1); + } else { + string_lowered = string_buf; + } + _XcmsCopyISOLatin1Lowered(string_lowered, prefix); + + /* + * First try Device-Independent color spaces + */ + papColorSpaces = _XcmsDIColorSpaces; + if (papColorSpaces != NULL) { + while (*papColorSpaces != NULL) { + if (strcmp((*papColorSpaces)->prefix, string_lowered) == 0) { + if (len >= sizeof(string_buf)) Xfree(string_lowered); + return((*papColorSpaces)->id); + } + papColorSpaces++; + } + } + + /* + * Next try Device-Dependent color spaces + */ + papColorSpaces = _XcmsDDColorSpaces; + if (papColorSpaces != NULL) { + while (*papColorSpaces != NULL) { + if (strcmp((*papColorSpaces)->prefix, string_lowered) == 0) { + if (len >= sizeof(string_buf)) Xfree(string_lowered); + return((*papColorSpaces)->id); + } + papColorSpaces++; + } + } + + if (len >= sizeof(string_buf)) Xfree(string_lowered); + return(XcmsUndefinedFormat); +} diff --git a/src/xcms/LRGB.c b/src/xcms/LRGB.c new file mode 100644 index 00000000..5b8b8068 --- /dev/null +++ b/src/xcms/LRGB.c @@ -0,0 +1,1813 @@ +/* $Xorg: LRGB.c,v 1.3 2000/08/17 19:44:39 cpqbld Exp $ */ + +/* + * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. + * All Rights Reserved + * + * This file is a component of an X Window System-specific implementation + * of Xcms based on the TekColor Color Management System. Permission is + * hereby granted to use, copy, modify, sell, and otherwise distribute this + * software and its documentation for any purpose and without fee, provided + * that this copyright, permission, and disclaimer notice is reproduced in + * all copies of this software and in supporting documentation. TekColor + * is a trademark of Tektronix, Inc. + * + * Tektronix makes no representation about the suitability of this software + * for any purpose. It is provided "as is" and with all faults. + * + * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, + * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX 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 THE PERFORMANCE OF THIS SOFTWARE. + * + * + * NAME + * XcmsLRGB.c + * + * DESCRIPTION + * This file contains the conversion routines: + * 1. CIE XYZ to RGB intensity + * 2. RGB intensity to device RGB + * 3. device RGB to RGB intensity + * 4. RGB intensity to CIE XYZ + * + */ + +#include <stdio.h> +#include <X11/Xos.h> +#include <X11/Xatom.h> +#include "Xlibint.h" +#include "Xcmsint.h" + +#ifdef __STDC__ +#define Const const +#else +#define Const /**/ +#endif + +/* + * EXTERNS + * External declarations required locally to this package + * that are not already declared in any of the included header + * files (external includes or internal includes). + */ +extern char _XcmsRGB_prefix[]; +extern char _XcmsRGBi_prefix[]; +extern unsigned long _XcmsGetElement(); +extern void _XcmsFreeIntensityMaps(); + + +/* + * LOCAL DEFINES + * #define declarations local to this package. + */ +#define EPS 0.001 +#ifndef MIN +#define MIN(x,y) ((x) > (y) ? (y) : (x)) +#endif /* MIN */ +#ifndef MAX +#define MAX(x,y) ((x) > (y) ? (x) : (y)) +#endif /* MAX */ +#ifndef MIN3 +#define MIN3(x,y,z) ((x) > (MIN((y), (z))) ? (MIN((y), (z))) : (x)) +#endif /* MIN3 */ +#ifndef MAX3 +#define MAX3(x,y,z) ((x) > (MAX((y), (z))) ? (x) : (MAX((y), (z)))) +#endif /* MAX3 */ + +/* + * LOCAL TYPEDEFS + * typedefs local to this package (for use with local vars). + * + */ + +/* + * FORWARD DECLARATIONS + */ +static void LINEAR_RGB_FreeSCCData(); +static int LINEAR_RGB_InitSCCData(); +static int XcmsLRGB_RGB_ParseString(); +static int XcmsLRGB_RGBi_ParseString(); +Status _XcmsGetTableType0(); +Status _XcmsGetTableType1(); + +/* + * LOCALS VARIABLES + * Variables local to this package. + * Usage example: + * static int ExampleLocalVar; + */ + +static unsigned short Const MASK[17] = { + 0x0000, /* 0 bitsPerRGB */ + 0x8000, /* 1 bitsPerRGB */ + 0xc000, /* 2 bitsPerRGB */ + 0xe000, /* 3 bitsPerRGB */ + 0xf000, /* 4 bitsPerRGB */ + 0xf800, /* 5 bitsPerRGB */ + 0xfc00, /* 6 bitsPerRGB */ + 0xfe00, /* 7 bitsPerRGB */ + 0xff00, /* 8 bitsPerRGB */ + 0xff80, /* 9 bitsPerRGB */ + 0xffc0, /* 10 bitsPerRGB */ + 0xffe0, /* 11 bitsPerRGB */ + 0xfff0, /* 12 bitsPerRGB */ + 0xfff8, /* 13 bitsPerRGB */ + 0xfffc, /* 14 bitsPerRGB */ + 0xfffe, /* 15 bitsPerRGB */ + 0xffff /* 16 bitsPerRGB */ +}; + + + /* + * A NULL terminated array of function pointers that when applied + * in series will convert an XcmsColor structure from XcmsRGBFormat + * to XcmsCIEXYZFormat. + */ +static XcmsConversionProc Fl_RGB_to_CIEXYZ[] = { + XcmsRGBToRGBi, + XcmsRGBiToCIEXYZ, + NULL +}; + + /* + * A NULL terminated array of function pointers that when applied + * in series will convert an XcmsColor structure from XcmsCIEXYZFormat + * to XcmsRGBFormat. + */ +static XcmsConversionProc Fl_CIEXYZ_to_RGB[] = { + XcmsCIEXYZToRGBi, + XcmsRGBiToRGB, + NULL +}; + + /* + * A NULL terminated array of function pointers that when applied + * in series will convert an XcmsColor structure from XcmsRGBiFormat + * to XcmsCIEXYZFormat. + */ +static XcmsConversionProc Fl_RGBi_to_CIEXYZ[] = { + XcmsRGBiToCIEXYZ, + NULL +}; + + /* + * A NULL terminated array of function pointers that when applied + * in series will convert an XcmsColor structure from XcmsCIEXYZFormat + * to XcmsRGBiFormat. + */ +static XcmsConversionProc Fl_CIEXYZ_to_RGBi[] = { + XcmsCIEXYZToRGBi, + NULL +}; + + /* + * RGBi Color Spaces + */ +XcmsColorSpace XcmsRGBiColorSpace = + { + _XcmsRGBi_prefix, /* prefix */ + XcmsRGBiFormat, /* id */ + XcmsLRGB_RGBi_ParseString, /* parseString */ + Fl_RGBi_to_CIEXYZ, /* to_CIEXYZ */ + Fl_CIEXYZ_to_RGBi, /* from_CIEXYZ */ + 1 + }; + + /* + * RGB Color Spaces + */ +XcmsColorSpace XcmsRGBColorSpace = + { + _XcmsRGB_prefix, /* prefix */ + XcmsRGBFormat, /* id */ + XcmsLRGB_RGB_ParseString, /* parseString */ + Fl_RGB_to_CIEXYZ, /* to_CIEXYZ */ + Fl_CIEXYZ_to_RGB, /* from_CIEXYZ */ + 1 + }; + + /* + * Device-Independent Color Spaces known to the + * LINEAR_RGB Screen Color Characteristics Function Set. + */ +static XcmsColorSpace *DDColorSpaces[] = { + &XcmsRGBColorSpace, + &XcmsRGBiColorSpace, + NULL +}; + + +/* + * GLOBALS + * Variables declared in this package that are allowed + * to be used globally. + */ + + /* + * LINEAR_RGB Screen Color Characteristics Function Set. + */ +XcmsFunctionSet XcmsLinearRGBFunctionSet = + { + &DDColorSpaces[0], /* pDDColorSpaces */ + LINEAR_RGB_InitSCCData, /* pInitScrnFunc */ + LINEAR_RGB_FreeSCCData /* pFreeSCCData */ + }; + +/* + * DESCRIPTION + * Contents of Default SCCData should be replaced if other + * data should be used as default. + * + * + */ + +/* + * NAME Tektronix 19" (Sony) CRT + * PART_NUMBER 119-2451-00 + * MODEL Tek4300, Tek4800 + */ + +static IntensityRec Const Default_RGB_RedTuples[] = { + /* {unsigned short value, XcmsFloat intensity} */ + 0x0000, 0.000000, + 0x0909, 0.000000, + 0x0a0a, 0.000936, + 0x0f0f, 0.001481, + 0x1414, 0.002329, + 0x1919, 0.003529, + 0x1e1e, 0.005127, + 0x2323, 0.007169, + 0x2828, 0.009699, + 0x2d2d, 0.012759, + 0x3232, 0.016392, + 0x3737, 0.020637, + 0x3c3c, 0.025533, + 0x4141, 0.031119, + 0x4646, 0.037431, + 0x4b4b, 0.044504, + 0x5050, 0.052373, + 0x5555, 0.061069, + 0x5a5a, 0.070624, + 0x5f5f, 0.081070, + 0x6464, 0.092433, + 0x6969, 0.104744, + 0x6e6e, 0.118026, + 0x7373, 0.132307, + 0x7878, 0.147610, + 0x7d7d, 0.163958, + 0x8282, 0.181371, + 0x8787, 0.199871, + 0x8c8c, 0.219475, + 0x9191, 0.240202, + 0x9696, 0.262069, + 0x9b9b, 0.285089, + 0xa0a0, 0.309278, + 0xa5a5, 0.334647, + 0xaaaa, 0.361208, + 0xafaf, 0.388971, + 0xb4b4, 0.417945, + 0xb9b9, 0.448138, + 0xbebe, 0.479555, + 0xc3c3, 0.512202, + 0xc8c8, 0.546082, + 0xcdcd, 0.581199, + 0xd2d2, 0.617552, + 0xd7d7, 0.655144, + 0xdcdc, 0.693971, + 0xe1e1, 0.734031, + 0xe6e6, 0.775322, + 0xebeb, 0.817837, + 0xf0f0, 0.861571, + 0xf5f5, 0.906515, + 0xfafa, 0.952662, + 0xffff, 1.000000 +}; + +static IntensityRec Const Default_RGB_GreenTuples[] = { + /* {unsigned short value, XcmsFloat intensity} */ + 0x0000, 0.000000, + 0x1313, 0.000000, + 0x1414, 0.000832, + 0x1919, 0.001998, + 0x1e1e, 0.003612, + 0x2323, 0.005736, + 0x2828, 0.008428, + 0x2d2d, 0.011745, + 0x3232, 0.015740, + 0x3737, 0.020463, + 0x3c3c, 0.025960, + 0x4141, 0.032275, + 0x4646, 0.039449, + 0x4b4b, 0.047519, + 0x5050, 0.056520, + 0x5555, 0.066484, + 0x5a5a, 0.077439, + 0x5f5f, 0.089409, + 0x6464, 0.102418, + 0x6969, 0.116485, + 0x6e6e, 0.131625, + 0x7373, 0.147853, + 0x7878, 0.165176, + 0x7d7d, 0.183604, + 0x8282, 0.203140, + 0x8787, 0.223783, + 0x8c8c, 0.245533, + 0x9191, 0.268384, + 0x9696, 0.292327, + 0x9b9b, 0.317351, + 0xa0a0, 0.343441, + 0xa5a5, 0.370580, + 0xaaaa, 0.398747, + 0xafaf, 0.427919, + 0xb4b4, 0.458068, + 0xb9b9, 0.489165, + 0xbebe, 0.521176, + 0xc3c3, 0.554067, + 0xc8c8, 0.587797, + 0xcdcd, 0.622324, + 0xd2d2, 0.657604, + 0xd7d7, 0.693588, + 0xdcdc, 0.730225, + 0xe1e1, 0.767459, + 0xe6e6, 0.805235, + 0xebeb, 0.843491, + 0xf0f0, 0.882164, + 0xf5f5, 0.921187, + 0xfafa, 0.960490, + 0xffff, 1.000000 +}; + +static IntensityRec Const Default_RGB_BlueTuples[] = { + /* {unsigned short value, XcmsFloat intensity} */ + 0x0000, 0.000000, + 0x0e0e, 0.000000, + 0x0f0f, 0.001341, + 0x1414, 0.002080, + 0x1919, 0.003188, + 0x1e1e, 0.004729, + 0x2323, 0.006766, + 0x2828, 0.009357, + 0x2d2d, 0.012559, + 0x3232, 0.016424, + 0x3737, 0.021004, + 0x3c3c, 0.026344, + 0x4141, 0.032489, + 0x4646, 0.039481, + 0x4b4b, 0.047357, + 0x5050, 0.056154, + 0x5555, 0.065903, + 0x5a5a, 0.076634, + 0x5f5f, 0.088373, + 0x6464, 0.101145, + 0x6969, 0.114968, + 0x6e6e, 0.129862, + 0x7373, 0.145841, + 0x7878, 0.162915, + 0x7d7d, 0.181095, + 0x8282, 0.200386, + 0x8787, 0.220791, + 0x8c8c, 0.242309, + 0x9191, 0.264937, + 0x9696, 0.288670, + 0x9b9b, 0.313499, + 0xa0a0, 0.339410, + 0xa5a5, 0.366390, + 0xaaaa, 0.394421, + 0xafaf, 0.423481, + 0xb4b4, 0.453547, + 0xb9b9, 0.484592, + 0xbebe, 0.516587, + 0xc3c3, 0.549498, + 0xc8c8, 0.583291, + 0xcdcd, 0.617925, + 0xd2d2, 0.653361, + 0xd7d7, 0.689553, + 0xdcdc, 0.726454, + 0xe1e1, 0.764013, + 0xe6e6, 0.802178, + 0xebeb, 0.840891, + 0xf0f0, 0.880093, + 0xf5f5, 0.919723, + 0xfafa, 0.959715, + 0xffff, 1.00000 +}; + +static IntensityTbl Default_RGB_RedTbl = { + /* IntensityRec *pBase */ + (IntensityRec *) Default_RGB_RedTuples, + /* unsigned int nEntries */ + 52 +}; + +static IntensityTbl Default_RGB_GreenTbl = { + /* IntensityRec *pBase */ + (IntensityRec *)Default_RGB_GreenTuples, + /* unsigned int nEntries */ + 50 +}; + +static IntensityTbl Default_RGB_BlueTbl = { + /* IntensityRec *pBase */ + (IntensityRec *)Default_RGB_BlueTuples, + /* unsigned int nEntries */ + 51 +}; + +static LINEAR_RGB_SCCData Default_RGB_SCCData = { + + /* XcmsFloat XYZtoRGBmatrix[3][3] */ + 3.48340481253539000, -1.52176374927285200, -0.55923133354049780, + -1.07152751306193600, 1.96593795204372400, 0.03673691339553462, + 0.06351179790497788, -0.20020501000496480, 0.81070942031648220, + + /* XcmsFloat RGBtoXYZmatrix[3][3] */ + 0.38106149108714790, 0.32025712365352110, 0.24834578525933100, + 0.20729745115140850, 0.68054638776373240, 0.11215616108485920, + 0.02133944350088028, 0.14297193020246480, 1.24172892629665500, + + /* IntensityTbl *pRedTbl */ + &Default_RGB_RedTbl, + + /* IntensityTbl *pGreenTbl */ + &Default_RGB_GreenTbl, + + /* IntensityTbl *pBlueTbl */ + &Default_RGB_BlueTbl +}; + +/************************************************************************ + * * + * PRIVATE ROUTINES * + * * + ************************************************************************/ + +/* + * NAME + * LINEAR_RGB_InitSCCData() + * + * SYNOPSIS + */ +static Status +LINEAR_RGB_InitSCCData(dpy, screenNumber, pPerScrnInfo) + Display *dpy; + int screenNumber; + XcmsPerScrnInfo *pPerScrnInfo; +/* + * DESCRIPTION + * + * RETURNS + * XcmsFailure if failed. + * XcmsSuccess if succeeded. + * + */ +{ + Atom CorrectAtom = XInternAtom (dpy, XDCCC_CORRECT_ATOM_NAME, True); + Atom MatrixAtom = XInternAtom (dpy, XDCCC_MATRIX_ATOM_NAME, True); + int format_return, count, cType, nTables; + unsigned long nitems, nbytes_return; + char *property_return, *pChar; + XcmsFloat *pValue; +#ifdef ALLDEBUG + IntensityRec *pIRec; +#endif /* ALLDEBUG */ + VisualID visualID; + + LINEAR_RGB_SCCData *pScreenData, *pScreenDefaultData; + XcmsIntensityMap *pNewMap; + + /* + * Allocate memory for pScreenData + */ + if (!(pScreenData = pScreenDefaultData = (LINEAR_RGB_SCCData *) + Xcalloc (1, sizeof(LINEAR_RGB_SCCData)))) { + return(XcmsFailure); + } + + /* + * 1. Get the XYZ->RGB and RGB->XYZ matrices + */ + + if (MatrixAtom == None || + !_XcmsGetProperty (dpy, RootWindow(dpy, screenNumber), MatrixAtom, + &format_return, &nitems, &nbytes_return, &property_return) || + nitems != 18 || format_return != 32) { + /* + * As per the XDCCC, there must be 18 data items and each must be + * in 32 bits ! + */ + goto FreeSCCData; + + } else { + + /* + * RGBtoXYZ and XYZtoRGB matrices + */ + pValue = (XcmsFloat *) pScreenData; + pChar = property_return; + for (count = 0; count < 18; count++) { + *pValue++ = (long)_XcmsGetElement(format_return, &pChar, + &nitems) / (XcmsFloat)XDCCC_NUMBER; + } + Xfree ((char *)property_return); + pPerScrnInfo->screenWhitePt.spec.CIEXYZ.X = + pScreenData->RGBtoXYZmatrix[0][0] + + pScreenData->RGBtoXYZmatrix[0][1] + + pScreenData->RGBtoXYZmatrix[0][2]; + pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y = + pScreenData->RGBtoXYZmatrix[1][0] + + pScreenData->RGBtoXYZmatrix[1][1] + + pScreenData->RGBtoXYZmatrix[1][2]; + pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Z = + pScreenData->RGBtoXYZmatrix[2][0] + + pScreenData->RGBtoXYZmatrix[2][1] + + pScreenData->RGBtoXYZmatrix[2][2]; + + /* + * Compute the Screen White Point + */ + if ((pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y < (1.0 - EPS) ) + || (pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y > (1.0 + EPS))) { + goto FreeSCCData; + } else { + pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y = 1.0; + } + pPerScrnInfo->screenWhitePt.format = XcmsCIEXYZFormat; + pPerScrnInfo->screenWhitePt.pixel = 0; + +#ifdef PDEBUG + printf ("RGB to XYZ Matrix values:\n"); + printf (" %f %f %f\n %f %f %f\n %f %f %f\n", + pScreenData->RGBtoXYZmatrix[0][0], + pScreenData->RGBtoXYZmatrix[0][1], + pScreenData->RGBtoXYZmatrix[0][2], + pScreenData->RGBtoXYZmatrix[1][0], + pScreenData->RGBtoXYZmatrix[1][1], + pScreenData->RGBtoXYZmatrix[1][2], + pScreenData->RGBtoXYZmatrix[2][0], + pScreenData->RGBtoXYZmatrix[2][1], + pScreenData->RGBtoXYZmatrix[2][2]); + printf ("XYZ to RGB Matrix values:\n"); + printf (" %f %f %f\n %f %f %f\n %f %f %f\n", + pScreenData->XYZtoRGBmatrix[0][0], + pScreenData->XYZtoRGBmatrix[0][1], + pScreenData->XYZtoRGBmatrix[0][2], + pScreenData->XYZtoRGBmatrix[1][0], + pScreenData->XYZtoRGBmatrix[1][1], + pScreenData->XYZtoRGBmatrix[1][2], + pScreenData->XYZtoRGBmatrix[2][0], + pScreenData->XYZtoRGBmatrix[2][1], + pScreenData->XYZtoRGBmatrix[2][2]); + printf ("Screen White Pt value: %f %f %f\n", + pPerScrnInfo->screenWhitePt.spec.CIEXYZ.X, + pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y, + pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Z); +#endif /* PDEBUG */ + } + + /* + * 2. Get the Intensity Profile + */ + if (CorrectAtom == None || + !_XcmsGetProperty (dpy, RootWindow(dpy, screenNumber), CorrectAtom, + &format_return, &nitems, &nbytes_return, &property_return)) { + Xfree ((char *)property_return); + goto FreeSCCData; + } + + pChar = property_return; + + while (nitems) { + switch (format_return) { + case 8: + /* + * Must have at least: + * VisualID0 + * VisualID1 + * VisualID2 + * VisualID3 + * type + * count + * length + * intensity1 + * intensity2 + */ + if (nitems < 9) { + Xfree ((char *)property_return); + goto FreeSCCData; + } + count = 3; + break; + case 16: + /* + * Must have at least: + * VisualID0 + * VisualID3 + * type + * count + * length + * intensity1 + * intensity2 + */ + if (nitems < 7) { + Xfree ((char *)property_return); + goto FreeSCCData; + } + count = 1; + break; + case 32: + /* + * Must have at least: + * VisualID0 + * type + * count + * length + * intensity1 + * intensity2 + */ + if (nitems < 6) { + Xfree ((char *)property_return); + goto FreeSCCData; + } + count = 0; + break; + default: + Xfree ((char *)property_return); + goto FreeSCCData; + } + + /* + * Get VisualID + */ + visualID = _XcmsGetElement(format_return, &pChar, &nitems); + while (count--) { + visualID = visualID << format_return; + visualID |= _XcmsGetElement(format_return, &pChar, &nitems); + } + + if (visualID == 0) { + /* + * This is a shared intensity table + */ + pScreenData = pScreenDefaultData; + } else { + /* + * This is a per-Visual intensity table + */ + if (!(pScreenData = (LINEAR_RGB_SCCData *) + Xcalloc (1, sizeof(LINEAR_RGB_SCCData)))) { + return(XcmsFailure); + } + /* copy matrices */ + memcpy((char *)pScreenData, (char *)pScreenDefaultData, + 18 * sizeof(XcmsFloat)); + + /* Create, initialize, and add map */ + if (!(pNewMap = (XcmsIntensityMap *) + Xcalloc (1, sizeof(XcmsIntensityMap)))) { + Xfree((char *)pScreenData); + return(XcmsFailure); + } + pNewMap->visualID = visualID; + pNewMap->screenData = (XPointer)pScreenData; + pNewMap->pFreeScreenData = LINEAR_RGB_FreeSCCData; + pNewMap->pNext = + (XcmsIntensityMap *)dpy->cms.perVisualIntensityMaps; + dpy->cms.perVisualIntensityMaps = (XPointer)pNewMap; + dpy->free_funcs->intensityMaps = _XcmsFreeIntensityMaps; + } + + cType = _XcmsGetElement(format_return, &pChar, &nitems); + nTables = _XcmsGetElement(format_return, &pChar, &nitems); + + if (cType == 0) { + + /* Red Intensity Table */ + if (!(pScreenData->pRedTbl = (IntensityTbl *) + Xcalloc (1, sizeof(IntensityTbl)))) { + goto FreeSCCData; + } + if (_XcmsGetTableType0(pScreenData->pRedTbl, format_return, &pChar, + &nitems) == XcmsFailure) { + goto FreeRedTbl; + } + + if (nTables == 1) { + /* Green Intensity Table */ + pScreenData->pGreenTbl = pScreenData->pRedTbl; + /* Blue Intensity Table */ + pScreenData->pBlueTbl = pScreenData->pRedTbl; + } else { + /* Green Intensity Table */ + if (!(pScreenData->pGreenTbl = (IntensityTbl *) + Xcalloc (1, sizeof(IntensityTbl)))) { + goto FreeRedTblElements; + } + if (_XcmsGetTableType0(pScreenData->pGreenTbl, format_return, &pChar, + &nitems) == XcmsFailure) { + goto FreeGreenTbl; + } + + /* Blue Intensity Table */ + if (!(pScreenData->pBlueTbl = (IntensityTbl *) + Xcalloc (1, sizeof(IntensityTbl)))) { + goto FreeGreenTblElements; + } + if (_XcmsGetTableType0(pScreenData->pBlueTbl, format_return, &pChar, + &nitems) == XcmsFailure) { + goto FreeBlueTbl; + } + } + } else if (cType == 1) { + /* Red Intensity Table */ + if (!(pScreenData->pRedTbl = (IntensityTbl *) + Xcalloc (1, sizeof(IntensityTbl)))) { + goto FreeSCCData; + } + if (_XcmsGetTableType1(pScreenData->pRedTbl, format_return, &pChar, + &nitems) == XcmsFailure) { + goto FreeRedTbl; + } + + if (nTables == 1) { + + /* Green Intensity Table */ + pScreenData->pGreenTbl = pScreenData->pRedTbl; + /* Blue Intensity Table */ + pScreenData->pBlueTbl = pScreenData->pRedTbl; + + } else { + + /* Green Intensity Table */ + if (!(pScreenData->pGreenTbl = (IntensityTbl *) + Xcalloc (1, sizeof(IntensityTbl)))) { + goto FreeRedTblElements; + } + if (_XcmsGetTableType1(pScreenData->pGreenTbl, format_return, &pChar, + &nitems) == XcmsFailure) { + goto FreeGreenTbl; + } + + /* Blue Intensity Table */ + if (!(pScreenData->pBlueTbl = (IntensityTbl *) + Xcalloc (1, sizeof(IntensityTbl)))) { + goto FreeBlueTblElements; + } + if (_XcmsGetTableType1(pScreenData->pBlueTbl, format_return, &pChar, + &nitems) == XcmsFailure) { + goto FreeBlueTbl; + } + } + } else { + Xfree ((char *)property_return); + goto FreeSCCData; + } + +#ifdef ALLDEBUG + printf ("Intensity Table RED %d\n", pScreenData->pRedTbl->nEntries); + pIRec = (IntensityRec *) pScreenData->pRedTbl->pBase; + for (count = 0; count < pScreenData->pRedTbl->nEntries; count++, pIRec++) { + printf ("\t0x%4x\t%f\n", pIRec->value, pIRec->intensity); + } + if (pScreenData->pGreenTbl->pBase != pScreenData->pRedTbl->pBase) { + printf ("Intensity Table GREEN %d\n", pScreenData->pGreenTbl->nEntries); + pIRec = (IntensityRec *)pScreenData->pGreenTbl->pBase; + for (count = 0; count < pScreenData->pGreenTbl->nEntries; count++, pIRec++) { + printf ("\t0x%4x\t%f\n", pIRec->value, pIRec->intensity); + } + } + if (pScreenData->pBlueTbl->pBase != pScreenData->pRedTbl->pBase) { + printf ("Intensity Table BLUE %d\n", pScreenData->pBlueTbl->nEntries); + pIRec = (IntensityRec *) pScreenData->pBlueTbl->pBase; + for (count = 0; count < pScreenData->pBlueTbl->nEntries; count++, pIRec++) { + printf ("\t0x%4x\t%f\n", pIRec->value, pIRec->intensity); + } + } +#endif /* ALLDEBUG */ + } + + Xfree ((char *)property_return); + + /* Free the old memory and use the new structure created. */ + LINEAR_RGB_FreeSCCData(pPerScrnInfo->screenData); + + pPerScrnInfo->functionSet = (XPointer) &XcmsLinearRGBFunctionSet; + + pPerScrnInfo->screenData = (XPointer) pScreenData; + + pPerScrnInfo->state = XcmsInitSuccess; + + return(XcmsSuccess); + +FreeBlueTblElements: + Xfree((char *)pScreenData->pBlueTbl->pBase); + +FreeBlueTbl: + Xfree((char *)pScreenData->pBlueTbl); + +FreeGreenTblElements: + Xfree((char *)pScreenData->pBlueTbl->pBase); + +FreeGreenTbl: + Xfree((char *)pScreenData->pGreenTbl); + +FreeRedTblElements: + Xfree((char *)pScreenData->pRedTbl->pBase); + +FreeRedTbl: + Xfree((char *)pScreenData->pRedTbl); + +FreeSCCData: + Xfree((char *)pScreenData); + pPerScrnInfo->state = XcmsInitNone; + return(XcmsFailure); +} + + +/* + * NAME + * LINEAR_RGB_FreeSCCData() + * + * SYNOPSIS + */ +static void +LINEAR_RGB_FreeSCCData(pScreenDataTemp) + XPointer pScreenDataTemp; +/* + * DESCRIPTION + * + * RETURNS + * 0 if failed. + * 1 if succeeded with no modifications. + * + */ +{ + LINEAR_RGB_SCCData *pScreenData = (LINEAR_RGB_SCCData *) pScreenDataTemp; + + if (pScreenData && pScreenData != &Default_RGB_SCCData) { + if (pScreenData->pRedTbl) { + if (pScreenData->pGreenTbl) { + if (pScreenData->pRedTbl->pBase != + pScreenData->pGreenTbl->pBase) { + if (pScreenData->pGreenTbl->pBase) { + Xfree ((char *)pScreenData->pGreenTbl->pBase); + } + } + if (pScreenData->pGreenTbl != pScreenData->pRedTbl) { + Xfree ((char *)pScreenData->pGreenTbl); + } + } + if (pScreenData->pBlueTbl) { + if (pScreenData->pRedTbl->pBase != + pScreenData->pBlueTbl->pBase) { + if (pScreenData->pBlueTbl->pBase) { + Xfree ((char *)pScreenData->pBlueTbl->pBase); + } + } + if (pScreenData->pBlueTbl != pScreenData->pRedTbl) { + Xfree ((char *)pScreenData->pBlueTbl); + } + } + if (pScreenData->pRedTbl->pBase) { + Xfree ((char *)pScreenData->pRedTbl->pBase); + } + Xfree ((char *)pScreenData->pRedTbl); + } + Xfree ((char *)pScreenData); + } +} + + + +/************************************************************************ + * * + * API PRIVATE ROUTINES * + * * + ************************************************************************/ + +/* + * NAME + * _XcmsGetTableType0 + * + * SYNOPSIS + */ +Status +_XcmsGetTableType0(pTbl, format, pChar, pCount) + IntensityTbl *pTbl; + int format; + char **pChar; + unsigned long *pCount; +/* + * DESCRIPTION + * + * RETURNS + * XcmsFailure if failed. + * XcmsSuccess if succeeded. + * + */ +{ + unsigned int nElements; + IntensityRec *pIRec; + + nElements = pTbl->nEntries = + _XcmsGetElement(format, pChar, pCount) + 1; + if (!(pIRec = pTbl->pBase = (IntensityRec *) + Xcalloc (nElements, sizeof(IntensityRec)))) { + return(XcmsFailure); + } + + switch (format) { + case 8: + for (; nElements--; pIRec++) { + /* 0xFFFF/0xFF = 0x101 */ + pIRec->value = _XcmsGetElement (format, pChar, pCount) * 0x101; + pIRec->intensity = + _XcmsGetElement (format, pChar, pCount) / (XcmsFloat)255.0; + } + break; + case 16: + for (; nElements--; pIRec++) { + pIRec->value = _XcmsGetElement (format, pChar, pCount); + pIRec->intensity = _XcmsGetElement (format, pChar, pCount) + / (XcmsFloat)65535.0; + } + break; + case 32: + for (; nElements--; pIRec++) { + pIRec->value = _XcmsGetElement (format, pChar, pCount); + pIRec->intensity = _XcmsGetElement (format, pChar, pCount) + / (XcmsFloat)4294967295.0; + } + break; + default: + return(XcmsFailure); + } + return(XcmsSuccess); +} + + +/* + * NAME + * _XcmsGetTableType1 + * + * SYNOPSIS + */ +Status +_XcmsGetTableType1(pTbl, format, pChar, pCount) + IntensityTbl *pTbl; + int format; + char **pChar; + unsigned long *pCount; +/* + * DESCRIPTION + * + * RETURNS + * XcmsFailure if failed. + * XcmsSuccess if succeeded. + * + */ +{ + int count; + unsigned int max_index; + IntensityRec *pIRec; + + max_index = _XcmsGetElement(format, pChar, pCount); + pTbl->nEntries = max_index + 1; + if (!(pIRec = pTbl->pBase = (IntensityRec *) + Xcalloc (max_index+1, sizeof(IntensityRec)))) { + return(XcmsFailure); + } + + switch (format) { + case 8: + for (count = 0; count < max_index+1; count++, pIRec++) { + pIRec->value = (count * 65535) / max_index; + pIRec->intensity = _XcmsGetElement (format, pChar, pCount) + / (XcmsFloat)255.0; + } + break; + case 16: + for (count = 0; count < max_index+1; count++, pIRec++) { + pIRec->value = (count * 65535) / max_index; + pIRec->intensity = _XcmsGetElement (format, pChar, pCount) + / (XcmsFloat)65535.0; + } + break; + case 32: + for (count = 0; count < max_index+1; count++, pIRec++) { + pIRec->value = (count * 65535) / max_index; + pIRec->intensity = _XcmsGetElement (format, pChar, pCount) + / (XcmsFloat)4294967295.0; + } + break; + default: + return(XcmsFailure); + } + + return(XcmsSuccess); +} + + +/* + * NAME + * ValueCmp + * + * SYNOPSIS + */ +int +_XcmsValueCmp (p1, p2) + IntensityRec *p1, *p2; +/* + * DESCRIPTION + * Compares the value component of two IntensityRec + * structures. + * + * RETURNS + * 0 if p1->value is equal to p2->value + * < 0 if p1->value is less than p2->value + * > 0 if p1->value is greater than p2->value + * + */ +{ + return (p1->value - p2->value); +} + + +/* + * NAME + * IntensityCmp + * + * SYNOPSIS + */ +int +_XcmsIntensityCmp (p1, p2) + IntensityRec *p1, *p2; +/* + * DESCRIPTION + * Compares the intensity component of two IntensityRec + * structures. + * + * RETURNS + * 0 if equal; + * < 0 if first precedes second + * > 0 if first succeeds second + * + */ +{ + if (p1->intensity < p2->intensity) { + return (-1); + } + if (p1->intensity > p2->intensity) { + return (XcmsSuccess); + } + return (XcmsFailure); +} + +/* + * NAME + * ValueInterpolation + * + * SYNOPSIS + */ +/* ARGSUSED */ +int +_XcmsValueInterpolation (key, lo, hi, answer, bitsPerRGB) + IntensityRec *key, *lo, *hi, *answer; + int bitsPerRGB; +/* + * DESCRIPTION + * Based on a given value, performs a linear interpolation + * on the intensities between two IntensityRec structures. + * Note that the bitsPerRGB parameter is ignored. + * + * RETURNS + * Returns 0 if failed; otherwise non-zero. + */ +{ + XcmsFloat ratio; + + ratio = ((XcmsFloat)key->value - (XcmsFloat)lo->value) / + ((XcmsFloat)hi->value - (XcmsFloat)lo->value); + answer->value = key->value; + answer->intensity = (hi->intensity - lo->intensity) * ratio; + answer->intensity += lo->intensity; + return (XcmsSuccess); +} + +/* + * NAME + * IntensityInterpolation + * + * SYNOPSIS + */ +int +_XcmsIntensityInterpolation (key, lo, hi, answer, bitsPerRGB) + IntensityRec *key, *lo, *hi, *answer; + int bitsPerRGB; +/* + * DESCRIPTION + * Based on a given intensity, performs a linear interpolation + * on the values between two IntensityRec structures. + * The bitsPerRGB parameter is necessary to perform rounding + * to the correct number of significant bits. + * + * RETURNS + * Returns 0 if failed; otherwise non-zero. + */ +{ + XcmsFloat ratio; + long target, up, down; + int shift = 16 - bitsPerRGB; + int max_color = (1 << bitsPerRGB) - 1; + + ratio = (key->intensity - lo->intensity) / (hi->intensity - lo->intensity); + answer->intensity = key->intensity; + target = hi->value - lo->value; + target *= ratio; + target += lo->value; + + /* + * Ok now, lets find the closest in respects to bits per RGB + */ + up = ((target >> shift) * 0xFFFF) / max_color; + if (up < target) { + down = up; + up = (MIN((down >> shift) + 1, max_color) * 0xFFFF) / max_color; + } else { + down = (MAX((up >> shift) - 1, 0) * 0xFFFF) / max_color; + } + answer->value = ((up - target) < (target - down) ? up : down); + answer->value &= MASK[bitsPerRGB]; + return (XcmsSuccess); +} + + +/* + * NAME + * _XcmsTableSearch + * + * SYNOPSIS + */ +int +_XcmsTableSearch (key, bitsPerRGB, base, nel, nKeyPtrSize, compar, interpol, answer) + char *key; + int bitsPerRGB; + char *base; + unsigned nel; + unsigned nKeyPtrSize; + int (*compar)(); + int (*interpol)(); + char *answer; + +/* + * DESCRIPTION + * A binary search through the specificied table. + * + * RETURNS + * Returns 0 if failed; otherwise non-zero. + * + */ +{ + char *hi, *lo, *mid, *last; + int result; + + last = hi = base + ((nel - 1) * nKeyPtrSize); + mid = lo = base; + + /* use only the significants bits, then scale into 16 bits */ + ((IntensityRec *)key)->value = ((unsigned long) + (((IntensityRec *)key)->value >> (16 - bitsPerRGB)) * 0xFFFF) + / ((1 << bitsPerRGB) - 1); + + /* Special case so that zero intensity always maps to zero value */ + if ((*compar) (key,lo) <= 0) { + memcpy (answer, lo, nKeyPtrSize); + ((IntensityRec *)answer)->value &= MASK[bitsPerRGB]; + return XcmsSuccess; + } + while (mid != last) { + last = mid; + mid = lo + (((unsigned)(hi - lo) / nKeyPtrSize) / 2) * nKeyPtrSize; + result = (*compar) (key, mid); + if (result == 0) { + + memcpy(answer, mid, nKeyPtrSize); + ((IntensityRec *)answer)->value &= MASK[bitsPerRGB]; + return (XcmsSuccess); + } else if (result < 0) { + hi = mid; + } else { + lo = mid; + } + } + + /* + * If we got to here, we didn't find a solution, so we + * need to apply interpolation. + */ + return ((*interpol)(key, lo, hi, answer, bitsPerRGB)); +} + + +/* + * NAME + * _XcmsMatVec - multiply a 3 x 3 by a 3 x 1 vector + * + * SYNOPSIS + */ +void _XcmsMatVec(pMat, pIn, pOut) + XcmsFloat *pMat, *pIn, *pOut; +/* + * DESCRIPTION + * Multiply the passed vector by the passed matrix to return a + * vector. Matrix is 3x3, vectors are of length 3. + * + * RETURNS + * void + */ +{ + int i, j; + + for (i = 0; i < 3; i++) { + pOut[i] = 0.0; + for (j = 0; j < 3; j++) + pOut[i] += *(pMat+(i*3)+j) * pIn[j]; + } +} + + +/************************************************************************ + * * + * PUBLIC ROUTINES * + * * + ************************************************************************/ + + +/* + * NAME + * XcmsLRGB_RGB_ParseString + * + * SYNOPSIS + */ +static int +XcmsLRGB_RGB_ParseString(spec, pColor) + register char *spec; + XcmsColor *pColor; +/* + * DESCRIPTION + * This routines takes a string and attempts to convert + * it into a XcmsColor structure with XcmsRGBFormat. + * + * RETURNS + * 0 if failed, non-zero otherwise. + */ +{ + register int n, i; + unsigned short r, g, b; + char c; + char *pchar; + unsigned short *pShort; + + /* + * Check for old # format + */ + if (*spec == '#') { + /* + * Attempt to parse the value portion. + */ + spec++; + n = strlen(spec); + if (n != 3 && n != 6 && n != 9 && n != 12) { + return(XcmsFailure); + } + + n /= 3; + g = b = 0; + do { + r = g; + g = b; + b = 0; + for (i = n; --i >= 0; ) { + c = *spec++; + b <<= 4; + if (c >= '0' && c <= '9') + b |= c - '0'; + /* assume string in lowercase + else if (c >= 'A' && c <= 'F') + b |= c - ('A' - 10); + */ + else if (c >= 'a' && c <= 'f') + b |= c - ('a' - 10); + else return (XcmsFailure); + } + } while (*spec != '\0'); + + /* + * Succeeded ! + */ + n <<= 2; + n = 16 - n; + /* shift instead of scale, to match old broken semantics */ + pColor->spec.RGB.red = r << n; + pColor->spec.RGB.green = g << n; + pColor->spec.RGB.blue = b << n; + } else { + if ((pchar = strchr(spec, ':')) == NULL) { + return(XcmsFailure); + } + n = (int)(pchar - spec); + + /* + * Check for proper prefix. + */ + if (strncmp(spec, _XcmsRGB_prefix, n) != 0) { + return(XcmsFailure); + } + + /* + * Attempt to parse the value portion. + */ + spec += (n + 1); + pShort = &pColor->spec.RGB.red; + for (i = 0; i < 3; i++, pShort++, spec++) { + n = 0; + *pShort = 0; + while (*spec != '/' && *spec != '\0') { + if (++n > 4) { + return(XcmsFailure); + } + c = *spec++; + *pShort <<= 4; + if (c >= '0' && c <= '9') + *pShort |= c - '0'; + /* assume string in lowercase + else if (c >= 'A' && c <= 'F') + *pShort |= c - ('A' - 10); + */ + else if (c >= 'a' && c <= 'f') + *pShort |= c - ('a' - 10); + else return (XcmsFailure); + } + if (n == 0) + return (XcmsFailure); + if (n < 4) { + *pShort = ((unsigned long)*pShort * 0xFFFF) / ((1 << n*4) - 1); + } + } + } + pColor->format = XcmsRGBFormat; + pColor->pixel = 0; + return (XcmsSuccess); +} + + +/* + * NAME + * XcmsLRGB_RGBi_ParseString + * + * SYNOPSIS + */ +static int +XcmsLRGB_RGBi_ParseString(spec, pColor) + register char *spec; + XcmsColor *pColor; +/* + * DESCRIPTION + * This routines takes a string and attempts to convert + * it into a XcmsColor structure with XcmsRGBiFormat. + * The assumed RGBi string syntax is: + * RGBi:<r>/<g>/<b> + * Where r, g, and b are in string input format for floats + * consisting of: + * a. an optional sign + * b. a string of numbers possibly containing a decimal point, + * c. an optional exponent field containing an 'E' or 'e' + * followed by a possibly signed integer string. + * + * RETURNS + * 0 if failed, non-zero otherwise. + */ +{ + int n; + char *pchar; + + if ((pchar = strchr(spec, ':')) == NULL) { + return(XcmsFailure); + } + n = (int)(pchar - spec); + + /* + * Check for proper prefix. + */ + if (strncmp(spec, _XcmsRGBi_prefix, n) != 0) { + return(XcmsFailure); + } + + /* + * Attempt to parse the value portion. + */ + if (sscanf(spec + n + 1, "%lf/%lf/%lf", + &pColor->spec.RGBi.red, + &pColor->spec.RGBi.green, + &pColor->spec.RGBi.blue) != 3) { + return(XcmsFailure); + } + + /* + * Succeeded ! + */ + pColor->format = XcmsRGBiFormat; + pColor->pixel = 0; + return (XcmsSuccess); +} + + +/* + * NAME + * XcmsCIEXYZToRGBi - convert CIE XYZ to RGB + * + * SYNOPSIS + */ +/* ARGSUSED */ +Status +XcmsCIEXYZToRGBi(ccc, pXcmsColors_in_out, nColors, pCompressed) + XcmsCCC ccc; + XcmsColor *pXcmsColors_in_out;/* pointer to XcmsColors to convert */ + unsigned int nColors; /* Number of colors */ + Bool *pCompressed; /* pointer to an array of Bool */ +/* + * DESCRIPTION + * Converts color specifications in an array of XcmsColor + * structures from RGB format to RGBi format. + * + * RETURNS + * XcmsFailure if failed, + * XcmsSuccess if succeeded without gamut compression. + * XcmsSuccessWithCompression if succeeded with gamut + * compression. + */ +{ + LINEAR_RGB_SCCData *pScreenData; + XcmsFloat tmp[3]; + int hasCompressed = 0; + unsigned int i; + XcmsColor *pColor = pXcmsColors_in_out; + + if (ccc == NULL) { + return(XcmsFailure); + } + + pScreenData = (LINEAR_RGB_SCCData *)ccc->pPerScrnInfo->screenData; + + /* + * XcmsColors should be White Point Adjusted, if necessary, by now! + */ + + /* + * NEW!!! for extended gamut compression + * + * 1. Need to zero out pCompressed + * + * 2. Need to save initial address of pColor + * + * 3. Need to save initial address of pCompressed + */ + + for (i = 0; i < nColors; i++) { + + /* Make sure format is XcmsCIEXYZFormat */ + if (pColor->format != XcmsCIEXYZFormat) { + return(XcmsFailure); + } + + /* Multiply [A]-1 * [XYZ] to get RGB intensity */ + _XcmsMatVec((XcmsFloat *) pScreenData->XYZtoRGBmatrix, + (XcmsFloat *) &pColor->spec, tmp); + + if ((MIN3 (tmp[0], tmp[1], tmp[2]) < -EPS) || + (MAX3 (tmp[0], tmp[1], tmp[2]) > (1.0 + EPS))) { + + /* + * RGBi out of screen's gamut + */ + + if (ccc->gamutCompProc == NULL) { + /* + * Aha!! Here's that little trick that will allow + * gamut compression routines to get the out of bound + * RGBi. + */ + memcpy((char *)&pColor->spec, (char *)tmp, sizeof(tmp)); + pColor->format = XcmsRGBiFormat; + return(XcmsFailure); + } else if ((*ccc->gamutCompProc)(ccc, pXcmsColors_in_out, nColors, + i, pCompressed) == 0) { + return(XcmsFailure); + } + + /* + * The gamut compression function should return colors in CIEXYZ + * Also check again to if the new color is within gamut. + */ + if (pColor->format != XcmsCIEXYZFormat) { + return(XcmsFailure); + } + _XcmsMatVec((XcmsFloat *) pScreenData->XYZtoRGBmatrix, + (XcmsFloat *) &pColor->spec, tmp); + if ((MIN3 (tmp[0], tmp[1], tmp[2]) < -EPS) || + (MAX3 (tmp[0], tmp[1], tmp[2]) > (1.0 + EPS))) { + return(XcmsFailure); + } + hasCompressed++; + } + memcpy((char *)&pColor->spec, (char *)tmp, sizeof(tmp)); + /* These if statements are done to ensure the fudge factor is */ + /* is taken into account. */ + if (pColor->spec.RGBi.red < 0.0) { + pColor->spec.RGBi.red = 0.0; + } else if (pColor->spec.RGBi.red > 1.0) { + pColor->spec.RGBi.red = 1.0; + } + if (pColor->spec.RGBi.green < 0.0) { + pColor->spec.RGBi.green = 0.0; + } else if (pColor->spec.RGBi.green > 1.0) { + pColor->spec.RGBi.green = 1.0; + } + if (pColor->spec.RGBi.blue < 0.0) { + pColor->spec.RGBi.blue = 0.0; + } else if (pColor->spec.RGBi.blue > 1.0) { + pColor->spec.RGBi.blue = 1.0; + } + (pColor++)->format = XcmsRGBiFormat; + } + return (hasCompressed ? XcmsSuccessWithCompression : XcmsSuccess); +} + + +/* + * NAME + * LINEAR_RGBi_to_CIEXYZ - convert RGBi to CIEXYZ + * + * SYNOPSIS + */ +/* ARGSUSED */ +Status +XcmsRGBiToCIEXYZ(ccc, pXcmsColors_in_out, nColors, pCompressed) + XcmsCCC ccc; + XcmsColor *pXcmsColors_in_out;/* pointer to XcmsColors to convert */ + unsigned int nColors; /* Number of colors */ + Bool *pCompressed; /* pointer to a bit array */ +/* + * DESCRIPTION + * Converts color specifications in an array of XcmsColor + * structures from RGBi format to CIEXYZ format. + * + * RETURNS + * XcmsFailure if failed, + * XcmsSuccess if succeeded. + */ +{ + LINEAR_RGB_SCCData *pScreenData; + XcmsFloat tmp[3]; + + /* + * pCompressed ignored in this function. + */ + + if (ccc == NULL) { + return(XcmsFailure); + } + + pScreenData = (LINEAR_RGB_SCCData *)ccc->pPerScrnInfo->screenData; + + /* + * XcmsColors should be White Point Adjusted, if necessary, by now! + */ + + while (nColors--) { + + /* Multiply [A]-1 * [XYZ] to get RGB intensity */ + _XcmsMatVec((XcmsFloat *) pScreenData->RGBtoXYZmatrix, + (XcmsFloat *) &pXcmsColors_in_out->spec, tmp); + + memcpy((char *)&pXcmsColors_in_out->spec, (char *)tmp, sizeof(tmp)); + (pXcmsColors_in_out++)->format = XcmsCIEXYZFormat; + } + return(XcmsSuccess); +} + + +/* + * NAME + * XcmsRGBiToRGB + * + * SYNOPSIS + */ +/* ARGSUSED */ +Status +XcmsRGBiToRGB(ccc, pXcmsColors_in_out, nColors, pCompressed) + XcmsCCC ccc; + XcmsColor *pXcmsColors_in_out;/* pointer to XcmsColors to convert */ + unsigned int nColors; /* Number of colors */ + Bool *pCompressed; /* pointer to a bit array */ +/* + * DESCRIPTION + * Converts color specifications in an array of XcmsColor + * structures from RGBi format to RGB format. + * + * RETURNS + * XcmsFailure if failed, + * XcmsSuccess if succeeded without gamut compression. + * XcmsSuccessWithCompression if succeeded with gamut + * compression. + */ +{ + LINEAR_RGB_SCCData *pScreenData; + XcmsRGB tmpRGB; + IntensityRec keyIRec, answerIRec; + + /* + * pCompressed ignored in this function. + */ + + if (ccc == NULL) { + return(XcmsFailure); + } + + pScreenData = (LINEAR_RGB_SCCData *)ccc->pPerScrnInfo->screenData; + + while (nColors--) { + + /* Make sure format is XcmsRGBiFormat */ + if (pXcmsColors_in_out->format != XcmsRGBiFormat) { + return(XcmsFailure); + } + + keyIRec.intensity = pXcmsColors_in_out->spec.RGBi.red; + if (!_XcmsTableSearch((char *)&keyIRec, ccc->visual->bits_per_rgb, + (char *)pScreenData->pRedTbl->pBase, + (unsigned)pScreenData->pRedTbl->nEntries, + (unsigned)sizeof(IntensityRec), + _XcmsIntensityCmp, _XcmsIntensityInterpolation, (char *)&answerIRec)) { + return(XcmsFailure); + } + tmpRGB.red = answerIRec.value; + + keyIRec.intensity = pXcmsColors_in_out->spec.RGBi.green; + if (!_XcmsTableSearch((char *)&keyIRec, ccc->visual->bits_per_rgb, + (char *)pScreenData->pGreenTbl->pBase, + (unsigned)pScreenData->pGreenTbl->nEntries, + (unsigned)sizeof(IntensityRec), + _XcmsIntensityCmp, _XcmsIntensityInterpolation, (char *)&answerIRec)) { + return(XcmsFailure); + } + tmpRGB.green = answerIRec.value; + + keyIRec.intensity = pXcmsColors_in_out->spec.RGBi.blue; + if (!_XcmsTableSearch((char *)&keyIRec, ccc->visual->bits_per_rgb, + (char *)pScreenData->pBlueTbl->pBase, + (unsigned)pScreenData->pBlueTbl->nEntries, + (unsigned)sizeof(IntensityRec), + _XcmsIntensityCmp, _XcmsIntensityInterpolation, (char *)&answerIRec)) { + return(XcmsFailure); + } + tmpRGB.blue = answerIRec.value; + + memcpy((char *)&pXcmsColors_in_out->spec, (char *)&tmpRGB, sizeof(XcmsRGB)); + (pXcmsColors_in_out++)->format = XcmsRGBFormat; + } + return(XcmsSuccess); +} + + +/* + * NAME + * XcmsRGBToRGBi + * + * SYNOPSIS + */ +/* ARGSUSED */ +Status +XcmsRGBToRGBi(ccc, pXcmsColors_in_out, nColors, pCompressed) + XcmsCCC ccc; + XcmsColor *pXcmsColors_in_out;/* pointer to XcmsColors to convert */ + unsigned int nColors; /* Number of colors */ + Bool *pCompressed; /* pointer to a bit array */ +/* + * DESCRIPTION + * Converts color specifications in an array of XcmsColor + * structures from RGB format to RGBi format. + * + * RETURNS + * XcmsFailure if failed, + * XcmsSuccess if succeeded. + */ +{ + LINEAR_RGB_SCCData *pScreenData; + XcmsRGBi tmpRGBi; + IntensityRec keyIRec, answerIRec; + + /* + * pCompressed ignored in this function. + */ + + if (ccc == NULL) { + return(XcmsFailure); + } + + pScreenData = (LINEAR_RGB_SCCData *)ccc->pPerScrnInfo->screenData; + + while (nColors--) { + + /* Make sure format is XcmsRGBFormat */ + if (pXcmsColors_in_out->format != XcmsRGBFormat) { + return(XcmsFailure); + } + + keyIRec.value = pXcmsColors_in_out->spec.RGB.red; + if (!_XcmsTableSearch((char *)&keyIRec, ccc->visual->bits_per_rgb, + (char *)pScreenData->pRedTbl->pBase, + (unsigned)pScreenData->pRedTbl->nEntries, + (unsigned)sizeof(IntensityRec), + _XcmsValueCmp, _XcmsValueInterpolation, (char *)&answerIRec)) { + return(XcmsFailure); + } + tmpRGBi.red = answerIRec.intensity; + + keyIRec.value = pXcmsColors_in_out->spec.RGB.green; + if (!_XcmsTableSearch((char *)&keyIRec, ccc->visual->bits_per_rgb, + (char *)pScreenData->pGreenTbl->pBase, + (unsigned)pScreenData->pGreenTbl->nEntries, + (unsigned)sizeof(IntensityRec), + _XcmsValueCmp, _XcmsValueInterpolation, (char *)&answerIRec)) { + return(XcmsFailure); + } + tmpRGBi.green = answerIRec.intensity; + + keyIRec.value = pXcmsColors_in_out->spec.RGB.blue; + if (!_XcmsTableSearch((char *)&keyIRec, ccc->visual->bits_per_rgb, + (char *)pScreenData->pBlueTbl->pBase, + (unsigned)pScreenData->pBlueTbl->nEntries, + (unsigned)sizeof(IntensityRec), + _XcmsValueCmp, _XcmsValueInterpolation, (char *)&answerIRec)) { + return(XcmsFailure); + } + tmpRGBi.blue = answerIRec.intensity; + + memcpy((char *)&pXcmsColors_in_out->spec, (char *)&tmpRGBi, sizeof(XcmsRGBi)); + (pXcmsColors_in_out++)->format = XcmsRGBiFormat; + } + return(XcmsSuccess); +} + +/* + * NAME + * _XcmsInitScrnDefaultInfo + * + * SYNOPSIS + */ +/* ARGSUSED */ +int +_XcmsLRGB_InitScrnDefault(dpy, screenNumber, pPerScrnInfo) + Display *dpy; + int screenNumber; + XcmsPerScrnInfo *pPerScrnInfo; +/* + * DESCRIPTION + * Given a display and screen number, this routine attempts + * to initialize the Xcms per Screen Info structure + * (XcmsPerScrnInfo) with defaults. + * + * RETURNS + * Returns zero if initialization failed; non-zero otherwise. + */ +{ + pPerScrnInfo->screenData = (XPointer)&Default_RGB_SCCData; + pPerScrnInfo->screenWhitePt.spec.CIEXYZ.X = + Default_RGB_SCCData.RGBtoXYZmatrix[0][0] + + Default_RGB_SCCData.RGBtoXYZmatrix[0][1] + + Default_RGB_SCCData.RGBtoXYZmatrix[0][2]; + pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y = + Default_RGB_SCCData.RGBtoXYZmatrix[1][0] + + Default_RGB_SCCData.RGBtoXYZmatrix[1][1] + + Default_RGB_SCCData.RGBtoXYZmatrix[1][2]; + pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Z = + Default_RGB_SCCData.RGBtoXYZmatrix[2][0] + + Default_RGB_SCCData.RGBtoXYZmatrix[2][1] + + Default_RGB_SCCData.RGBtoXYZmatrix[2][2]; + if ((pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y < (1.0 - EPS) ) + || (pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y > (1.0 + EPS))) { + pPerScrnInfo->screenData = (XPointer)NULL; + pPerScrnInfo->state = XcmsInitNone; + return(0); + } + pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y = 1.0; + pPerScrnInfo->screenWhitePt.format = XcmsCIEXYZFormat; + pPerScrnInfo->screenWhitePt.pixel = 0; + pPerScrnInfo->functionSet = (XPointer)&XcmsLinearRGBFunctionSet; + pPerScrnInfo->state = XcmsInitFailure; /* default initialization */ + return(1); +} diff --git a/src/xcms/Lab.c b/src/xcms/Lab.c new file mode 100644 index 00000000..7827d8e7 --- /dev/null +++ b/src/xcms/Lab.c @@ -0,0 +1,416 @@ +/* $Xorg: Lab.c,v 1.3 2000/08/17 19:44:39 cpqbld Exp $ */ + +/* + * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. + * All Rights Reserved + * + * This file is a component of an X Window System-specific implementation + * of XCMS based on the TekColor Color Management System. Permission is + * hereby granted to use, copy, modify, sell, and otherwise distribute this + * software and its documentation for any purpose and without fee, provided + * that this copyright, permission, and disclaimer notice is reproduced in + * all copies of this software and in supporting documentation. TekColor + * is a trademark of Tektronix, Inc. + * + * Tektronix makes no representation about the suitability of this software + * for any purpose. It is provided "as is" and with all faults. + * + * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, + * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX 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 THE PERFORMANCE OF THIS SOFTWARE. + * + * + * NAME + * CIELab.c + * + * DESCRIPTION + * This file contains routines that support the CIE L*a*b* + * color space to include conversions to and from the CIE + * XYZ space. These conversions are from Principles of + * Color Technology Second Edition, Fred W. Billmeyer, Jr. + * and Max Saltzman, John Wiley & Sons, Inc., 1981. + * + * Note that the range for L* is 0 to 1. + */ + + +#include <X11/Xos.h> +#include "Xlibint.h" +#include "Xcmsint.h" + +/* + * DEFINES + * Internal definitions that need NOT be exported to any package + * or program using this package. + */ +#ifdef DBL_EPSILON +# define XMY_DBL_EPSILON DBL_EPSILON +#else +# define XMY_DBL_EPSILON 0.00001 +#endif +#define DIV16BY116 0.137931 + +/* + * EXTERNS + */ +extern char _XcmsCIELab_prefix[]; + + +/* + * FORWARD DECLARATIONS + */ + +static int CIELab_ParseString(); +static Status XcmsCIELab_ValidSpec(); + + +/* + * LOCAL VARIABLES + */ + + + /* + * NULL terminated list of functions applied to get from CIELab to CIEXYZ + */ +static XcmsConversionProc Fl_CIELab_to_CIEXYZ[] = { + XcmsCIELabToCIEXYZ, + NULL +}; + + /* + * NULL terminated list of functions applied to get from CIEXYZ to CIELab + */ +static XcmsConversionProc Fl_CIEXYZ_to_CIELab[] = { + XcmsCIEXYZToCIELab, + NULL +}; + + +/* + * GLOBALS + */ + /* + * CIE Lab Color Space + */ +XcmsColorSpace XcmsCIELabColorSpace = + { + _XcmsCIELab_prefix, /* prefix */ + XcmsCIELabFormat, /* id */ + CIELab_ParseString, /* parseString */ + Fl_CIELab_to_CIEXYZ, /* to_CIEXYZ */ + Fl_CIEXYZ_to_CIELab, /* from_CIEXYZ */ + 1 + }; + + +/************************************************************************ + * * + * PRIVATE ROUTINES * + * * + ************************************************************************/ + +/* + * NAME + * CIELab_ParseString + * + * SYNOPSIS + */ +static int +CIELab_ParseString(spec, pColor) + register char *spec; + XcmsColor *pColor; +/* + * DESCRIPTION + * This routines takes a string and attempts to convert + * it into a XcmsColor structure with XcmsCIELabFormat. + * The assumed CIELab string syntax is: + * CIELab:<L>/<a>/<b> + * Where L, a, and b are in string input format for floats + * consisting of: + * a. an optional sign + * b. a string of numbers possibly containing a decimal point, + * c. an optional exponent field containing an 'E' or 'e' + * followed by a possibly signed integer string. + * + * RETURNS + * 0 if failed, non-zero otherwise. + */ +{ + int n; + char *pchar; + + if ((pchar = strchr(spec, ':')) == NULL) { + return(XcmsFailure); + } + n = (int)(pchar - spec); + + /* + * Check for proper prefix. + */ + if (strncmp(spec, _XcmsCIELab_prefix, n) != 0) { + return(XcmsFailure); + } + + /* + * Attempt to parse the value portion. + */ + if (sscanf(spec + n + 1, "%lf/%lf/%lf", + &pColor->spec.CIELab.L_star, + &pColor->spec.CIELab.a_star, + &pColor->spec.CIELab.b_star) != 3) { + return(XcmsFailure); + } + pColor->format = XcmsCIELabFormat; + pColor->pixel = 0; + + return(XcmsCIELab_ValidSpec(pColor)); +} + + + +/************************************************************************ + * * + * PUBLIC ROUTINES * + * * + ************************************************************************/ + +/* + * NAME + * XcmsCIELab_ValidSpec + * + * SYNOPSIS + */ +static Status +XcmsCIELab_ValidSpec(pColor) + XcmsColor *pColor; +/* + * DESCRIPTION + * Checks if color specification valid for CIE L*a*b*. + * + * RETURNS + * XcmsFailure if invalid, + * XcmsSuccess if valid. + * + */ +{ + if (pColor->format != XcmsCIELabFormat + || + (pColor->spec.CIELab.L_star < 0.0 - XMY_DBL_EPSILON) + || + (pColor->spec.CIELab.L_star > 100.0 + XMY_DBL_EPSILON)) { + return(XcmsFailure); + } + return(XcmsSuccess); +} + + +/* + * NAME + * XcmsCIELabToCIEXYZ - convert CIELab to CIEXYZ + * + * SYNOPSIS + */ +Status +XcmsCIELabToCIEXYZ(ccc, pLab_WhitePt, pColors_in_out, nColors) + XcmsCCC ccc; + XcmsColor *pLab_WhitePt; + XcmsColor *pColors_in_out; + unsigned int nColors; +/* + * DESCRIPTION + * Converts color specifications in an array of XcmsColor + * structures from CIELab format to CIEXYZ format. + * + * WARNING: This routine assumes that Yn = 1.0; + * + * RETURNS + * XcmsFailure if failed, + * XcmsSuccess if succeeded. + * + */ +{ + XcmsCIEXYZ XYZ_return; + XcmsFloat tmpFloat, tmpL; + XcmsColor whitePt; + int i; + XcmsColor *pColor = pColors_in_out; + + /* + * Check arguments + */ + if (pLab_WhitePt == NULL || pColors_in_out == NULL) { + return(XcmsFailure); + } + + /* + * Make sure white point is in CIEXYZ form, if not, convert it. + */ + if (pLab_WhitePt->format != XcmsCIEXYZFormat) { + /* Make a copy of the white point because we're going to modify it */ + memcpy((char *)&whitePt, (char *)pLab_WhitePt, sizeof(XcmsColor)); + if (!_XcmsDIConvertColors(ccc, &whitePt, + (XcmsColor *)NULL, 1, XcmsCIEXYZFormat)) { + return(XcmsFailure); + } + pLab_WhitePt = &whitePt; + } + + /* + * Make sure it is a white point, i.e., Y == 1.0 + */ + if (pLab_WhitePt->spec.CIEXYZ.Y != 1.0) { + return (0); + } + + /* + * Now convert each XcmsColor structure to CIEXYZ form + */ + for (i = 0; i < nColors; i++, pColor++) { + + /* Make sure original format is CIELab */ + if (!XcmsCIELab_ValidSpec(pColor)) { + return(XcmsFailure); + } + + /* Calculate Y: assume that Yn = 1.0 */ + tmpL = (pColor->spec.CIELab.L_star + 16.0) / 116.0; + XYZ_return.Y = tmpL * tmpL * tmpL; + + if (XYZ_return.Y < 0.008856) { + /* Calculate Y: assume that Yn = 1.0 */ + tmpL = pColor->spec.CIELab.L_star / 9.03292; + + /* Calculate X */ + XYZ_return.X = pLab_WhitePt->spec.CIEXYZ.X * + ((pColor->spec.CIELab.a_star / 3893.5) + tmpL); + /* Calculate Y */ + XYZ_return.Y = tmpL; + /* Calculate Z */ + XYZ_return.Z = pLab_WhitePt->spec.CIEXYZ.Z * + (tmpL - (pColor->spec.CIELab.b_star / 1557.4)); + } else { + /* Calculate X */ + tmpFloat = tmpL + (pColor->spec.CIELab.a_star / 5.0); + XYZ_return.X = pLab_WhitePt->spec.CIEXYZ.X * tmpFloat * tmpFloat * tmpFloat; + + /* Calculate Z */ + tmpFloat = tmpL - (pColor->spec.CIELab.b_star / 2.0); + XYZ_return.Z = pLab_WhitePt->spec.CIEXYZ.Z * tmpFloat * tmpFloat * tmpFloat; + } + + memcpy((char *)&pColor->spec.CIEXYZ, (char *)&XYZ_return, + sizeof(XcmsCIEXYZ)); + pColor->format = XcmsCIEXYZFormat; + } + + return (1); +} + + +/* + * NAME + * XcmsCIEXYZToCIELab - convert CIEXYZ to CIELab + * + * SYNOPSIS + */ +Status +XcmsCIEXYZToCIELab(ccc, pLab_WhitePt, pColors_in_out, nColors) + XcmsCCC ccc; + XcmsColor *pLab_WhitePt; + XcmsColor *pColors_in_out; + unsigned int nColors; +/* + * DESCRIPTION + * Converts color specifications in an array of XcmsColor + * structures from CIEXYZ format to CIELab format. + * + * WARNING: This routine assumes that Yn = 1.0; + * + * RETURNS + * XcmsFailure if failed, + * XcmsSuccess if succeeded. + * + */ +{ + XcmsCIELab Lab_return; + XcmsFloat fX_Xn, fY_Yn, fZ_Zn; + XcmsColor whitePt; + int i; + XcmsColor *pColor = pColors_in_out; + + /* + * Check arguments + */ + if (pLab_WhitePt == NULL || pColors_in_out == NULL) { + return(XcmsFailure); + } + + /* + * Make sure white point is in CIEXYZ form, if not, convert it. + */ + if (pLab_WhitePt->format != XcmsCIEXYZFormat) { + /* Make a copy of the white point because we're going to modify it */ + memcpy((char *)&whitePt, (char *)pLab_WhitePt, sizeof(XcmsColor)); + if (!_XcmsDIConvertColors(ccc, &whitePt, (XcmsColor *)NULL, + 1, XcmsCIEXYZFormat)) { + return(XcmsFailure); + } + pLab_WhitePt = &whitePt; + } + + /* + * Make sure it is a white point, i.e., Y == 1.0 + */ + if (pLab_WhitePt->spec.CIEXYZ.Y != 1.0) { + return(XcmsFailure); + } + + /* + * Now convert each XcmsColor structure to CIEXYZ form + */ + for (i = 0; i < nColors; i++, pColor++) { + + /* Make sure original format is CIELab */ + if (!_XcmsCIEXYZ_ValidSpec(pColor)) { + return(XcmsFailure); + } + + /* Calculate L*: assume Yn = 1.0 */ + if (pColor->spec.CIEXYZ.Y < 0.008856) { + fY_Yn = (0.07787 * pColor->spec.CIEXYZ.Y) + DIV16BY116; + /* note fY_Yn used to compute Lab_return.a below */ + Lab_return.L_star = 116.0 * (fY_Yn - DIV16BY116); + } else { + fY_Yn = (XcmsFloat)XCMS_CUBEROOT(pColor->spec.CIEXYZ.Y); + /* note fY_Yn used to compute Lab_return.a_star below */ + Lab_return.L_star = (116.0 * fY_Yn) - 16.0; + } + + /* Calculate f(X/Xn) */ + if ((fX_Xn = pColor->spec.CIEXYZ.X / pLab_WhitePt->spec.CIEXYZ.X) < 0.008856) { + fX_Xn = (0.07787 * fX_Xn) + DIV16BY116; + } else { + fX_Xn = (XcmsFloat) XCMS_CUBEROOT(fX_Xn); + } + + /* Calculate f(Z/Zn) */ + if ((fZ_Zn = pColor->spec.CIEXYZ.Z / pLab_WhitePt->spec.CIEXYZ.Z) < 0.008856) { + fZ_Zn = (0.07787 * fZ_Zn) + DIV16BY116; + } else { + fZ_Zn = (XcmsFloat) XCMS_CUBEROOT(fZ_Zn); + } + + Lab_return.a_star = 5.0 * (fX_Xn - fY_Yn); + Lab_return.b_star = 2.0 * (fY_Yn - fZ_Zn); + + memcpy((char *)&pColor->spec.CIELab, (char *)&Lab_return, + sizeof(XcmsCIELab)); + pColor->format = XcmsCIELabFormat; + } + + return(XcmsSuccess); +} diff --git a/src/xcms/LabGcC.c b/src/xcms/LabGcC.c new file mode 100644 index 00000000..0618dcbb --- /dev/null +++ b/src/xcms/LabGcC.c @@ -0,0 +1,124 @@ +/* $Xorg: LabGcC.c,v 1.3 2000/08/17 19:44:39 cpqbld Exp $ */ + +/* + * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. + * All Rights Reserved + * + * This file is a component of an X Window System-specific implementation + * of XCMS based on the TekColor Color Management System. Permission is + * hereby granted to use, copy, modify, sell, and otherwise distribute this + * software and its documentation for any purpose and without fee, provided + * that this copyright, permission, and disclaimer notice is reproduced in + * all copies of this software and in supporting documentation. TekColor + * is a trademark of Tektronix, Inc. + * + * Tektronix makes no representation about the suitability of this software + * for any purpose. It is provided "as is" and with all faults. + * + * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, + * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX 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 THE PERFORMANCE OF THIS SOFTWARE. + * + * NAME + * CIELabGcC.c + * + * DESCRIPTION + * Source for XcmsCIELabClipuv() gamut compression routine. + * + */ + +#include "Xlibint.h" +#include "Xcmsint.h" + + +/************************************************************************ + * * + * PUBLIC ROUTINES * + * * + ************************************************************************/ + +/* + * NAME + * XcmsCIELabClipab - Reduce the chroma for a hue and L* + * + * SYNOPSIS + */ +/* ARGSUSED */ +Status +XcmsCIELabClipab (ccc, pColors_in_out, nColors, i, pCompressed) + XcmsCCC ccc; + XcmsColor *pColors_in_out; + unsigned int nColors; + unsigned int i; + Bool *pCompressed; +/* + * DESCRIPTION + * Reduce the Chroma for a specific hue and chroma to + * to bring the given color into the gamut of the + * specified device. As required of gamut compression + * functions, this routine returns pColor_in_out + * in XcmsCIEXYZFormat on successful completion. + * + * Since this routine works with the L* within + * pColor_in_out intermediate results may be returned + * even though it may be invalid. + * + * RETURNS + * XcmsFailure - Failure + * XcmsSuccess - Succeeded + * + */ +{ + Status retval; + XcmsColor *pColor; + + /* + * Color specification passed as input can be assumed to: + * 1. Be in XcmsCIEXYZFormat + * 2. Already be white point adjusted for the Screen White Point. + * This means that the white point now associated with this + * color spec is the Screen White Point (even if the + * ccc->clientWhitePt differs). + */ + + pColor = pColors_in_out + i; + + if (ccc->visual->class < PseudoColor) { + /* + * GRAY ! + */ + _XcmsDIConvertColors(ccc, pColor, ScreenWhitePointOfCCC(ccc), + 1, XcmsCIELabFormat); + _XcmsDIConvertColors(ccc, pColor, ScreenWhitePointOfCCC(ccc), + 1, XcmsCIEXYZFormat); + if (pCompressed) { + *(pCompressed + i) = True; + } + return(XcmsSuccess); + } else { + if (pColor->format != XcmsCIELabFormat) { + if (_XcmsDIConvertColors(ccc, pColor, + &ccc->pPerScrnInfo->screenWhitePt, 1, XcmsCIELabFormat) + == XcmsFailure) { + return(XcmsFailure); + } + } + if (XcmsCIELabQueryMaxC(ccc, + degrees(XCMS_CIELAB_PMETRIC_HUE(pColor->spec.CIELab.a_star, + pColor->spec.CIELab.b_star)), + pColor->spec.CIELab.L_star, + pColor) == XcmsFailure) { + return(XcmsFailure); + } + retval = _XcmsDIConvertColors(ccc, pColor, + &ccc->pPerScrnInfo->screenWhitePt, 1, XcmsCIEXYZFormat); + if (retval != XcmsFailure && pCompressed != NULL) { + *(pCompressed + i) = True; + } + return(retval); + } +} diff --git a/src/xcms/LabGcL.c b/src/xcms/LabGcL.c new file mode 100644 index 00000000..bc6d20ef --- /dev/null +++ b/src/xcms/LabGcL.c @@ -0,0 +1,176 @@ +/* $Xorg: LabGcL.c,v 1.3 2000/08/17 19:44:39 cpqbld Exp $ */ + +/* + * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. + * All Rights Reserved + * + * This file is a component of an X Window System-specific implementation + * of XCMS based on the TekColor Color Management System. Permission is + * hereby granted to use, copy, modify, sell, and otherwise distribute this + * software and its documentation for any purpose and without fee, provided + * that this copyright, permission, and disclaimer notice is reproduced in + * all copies of this software and in supporting documentation. TekColor + * is a trademark of Tektronix, Inc. + * + * Tektronix makes no representation about the suitability of this software + * for any purpose. It is provided "as is" and with all faults. + * + * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, + * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX 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 THE PERFORMANCE OF THIS SOFTWARE. + * + * NAME + * CIELabGcL.c + * + * DESCRIPTION + * Source for XcmsCIELabClipL() gamut compression routine. + * + */ + +#include "Xlibint.h" +#include "Xcmsint.h" + +/* + * EXTERNS + */ +extern Status _XcmsCIELabQueryMaxLCRGB(); + + +/************************************************************************ + * * + * PUBLIC ROUTINES * + * * + ************************************************************************/ + +/* + * NAME + * XcmsCIELabClipL - Return the closest L* + * + * SYNOPSIS + */ +/* ARGSUSED */ +Status +XcmsCIELabClipL (ccc, pColors_in_out, nColors, i, pCompressed) + XcmsCCC ccc; + XcmsColor *pColors_in_out; + unsigned int nColors; + unsigned int i; + Bool *pCompressed; +/* + * DESCRIPTION + * Return the closest L* for a specific hue and chroma. + * This routine takes any color as input and outputs + * a CIE XYZ color. + * + * Since this routine works with the L* within + * pColor_in_out intermediate results may be returned + * even though it may be invalid. + * + * RETURNS + * XcmsFailure - Failure + * XcmsSuccess - Succeeded + * + */ +{ + XcmsCCCRec myCCC; + XcmsColor *pColor; + XcmsColor Lab_max; + XcmsFloat hue, chroma, maxChroma; + Status retval; + + /* Use my own CCC */ + memcpy ((char *)&myCCC, (char *)ccc, sizeof(XcmsCCCRec)); + myCCC.clientWhitePt.format = XcmsUndefinedFormat;/* Inherit Screen WP */ + myCCC.gamutCompProc = (XcmsCompressionProc)NULL;/* no gamut compression */ + + /* + * Color specification passed as input can be assumed to: + * 1. Be in XcmsCIEXYZFormat + * 2. Already be white point adjusted for the Screen White Point. + * This means that the white point now associated with this + * color spec is the Screen White Point (even if the + * ccc->clientWhitePt differs). + */ + + pColor = pColors_in_out + i; + + if (ccc->visual->class < StaticColor) { + /* + * GRAY ! + */ + return(XcmsFailure); + } else { + /* Convert from CIEXYZ to CIE L*u*v* format */ + if (_XcmsDIConvertColors(&myCCC, pColor, + ScreenWhitePointOfCCC(&myCCC), 1, XcmsCIELabFormat) + == XcmsFailure) { + return(XcmsFailure); + } + + hue = XCMS_CIELAB_PMETRIC_HUE(pColor->spec.CIELab.a_star, + pColor->spec.CIELab.b_star); + chroma = XCMS_CIELAB_PMETRIC_CHROMA(pColor->spec.CIELab.a_star, + pColor->spec.CIELab.b_star); + /* Step 1: compute the maximum L* and chroma for this hue. */ + /* This copy may be overkill but it preserves the pixel etc. */ + memcpy((char *)&Lab_max, (char *)pColor, sizeof(XcmsColor)); + if (_XcmsCIELabQueryMaxLCRGB (&myCCC, hue, &Lab_max, + (XcmsRGBi *)NULL) == XcmsFailure) { + return (XcmsFailure); + } + maxChroma = XCMS_CIELAB_PMETRIC_CHROMA(Lab_max.spec.CIELab.a_star, + Lab_max.spec.CIELab.b_star); + + /* Now check and return the appropriate L* */ + if (chroma == maxChroma) { + /* When the chroma input is equal to the maximum chroma */ + /* merely return the L* for that chroma. */ + memcpy((char *)pColor, (char *)&Lab_max, sizeof(XcmsColor)); + retval = _XcmsDIConvertColors(&myCCC, pColor, + ScreenWhitePointOfCCC(&myCCC), 1, XcmsCIEXYZFormat); + } else if (chroma > maxChroma) { + /* When the chroma input is greater than the maximum chroma */ + /* merely return the L* and chroma for the given hue. */ + memcpy((char *)pColor, (char *)&Lab_max, sizeof(XcmsColor)); + return (XcmsFailure); + } else if (pColor->spec.CIELab.L_star < Lab_max.spec.CIELab.L_star) { + /* Find the minimum lightness for the given chroma. */ + if (pColor->format != XcmsCIELabFormat) { + if (_XcmsDIConvertColors(ccc, pColor, + ScreenWhitePointOfCCC(ccc), 1, XcmsCIELabFormat) + == XcmsFailure) { + return(XcmsFailure); + } + } + if (XcmsCIELabQueryMinL(&myCCC, degrees(hue), chroma, pColor) + == XcmsFailure) { + return (XcmsFailure); + } + retval = _XcmsDIConvertColors(&myCCC, pColor, + ScreenWhitePointOfCCC(&myCCC), 1, XcmsCIEXYZFormat); + } else { + /* Find the maximum lightness for the given chroma. */ + if (pColor->format != XcmsCIELabFormat) { + if (_XcmsDIConvertColors(ccc, pColor, + ScreenWhitePointOfCCC(ccc), 1, XcmsCIELabFormat) + == XcmsFailure) { + return(XcmsFailure); + } + } + if (XcmsCIELabQueryMaxL(&myCCC, degrees(hue), chroma, pColor) + == XcmsFailure) { + return (XcmsFailure); + } + retval = _XcmsDIConvertColors(&myCCC, pColor, + ScreenWhitePointOfCCC(&myCCC), 1, XcmsCIEXYZFormat); + } + if (retval != XcmsFailure && pCompressed != NULL) { + *(pCompressed + i) = True; + } + return(retval); + } +} diff --git a/src/xcms/LabGcLC.c b/src/xcms/LabGcLC.c new file mode 100644 index 00000000..8ffaf8c3 --- /dev/null +++ b/src/xcms/LabGcLC.c @@ -0,0 +1,225 @@ +/* $Xorg: LabGcLC.c,v 1.3 2000/08/17 19:44:39 cpqbld Exp $ */ + +/* + * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. + * All Rights Reserved + * + * This file is a component of an X Window System-specific implementation + * of XCMS based on the TekColor Color Management System. Permission is + * hereby granted to use, copy, modify, sell, and otherwise distribute this + * software and its documentation for any purpose and without fee, provided + * that this copyright, permission, and disclaimer notice is reproduced in + * all copies of this software and in supporting documentation. TekColor + * is a trademark of Tektronix, Inc. + * + * Tektronix makes no representation about the suitability of this software + * for any purpose. It is provided "as is" and with all faults. + * + * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, + * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX 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 THE PERFORMANCE OF THIS SOFTWARE. + * + * NAME + * CIELabGcLC.c + * + * DESCRIPTION + * Source for XcmsCIELabClipLab() gamut + * compression function. + */ + +#include "Xlibint.h" +#include "Xcmsint.h" +#include <math.h> + +/* + * INTERNALS + * Internal defines that need NOT be exported to any package or + * program using this package. + */ +#define MAXBISECTCOUNT 100 + +/* + * EXTERNS + */ +extern Status _XcmsCIELabQueryMaxLCRGB(); + + +/************************************************************************ + * * + * PUBLIC ROUTINES * + * * + ************************************************************************/ + +/* + * NAME + * XcmsCIELabClipLab - Return the closest L* and chroma + * + * SYNOPSIS + */ +/* ARGSUSED */ +Status +XcmsCIELabClipLab (ccc, pColors_in_out, nColors, i, pCompressed) + XcmsCCC ccc; + XcmsColor *pColors_in_out; + unsigned int nColors; + unsigned int i; + Bool *pCompressed; +/* + * DESCRIPTION + * This routine will find the closest L* and chroma + * for a specific hue. The color input is converted to + * CIE L*u*v* format and returned as CIE XYZ format. + * + * Since this routine works with the L* within + * pColor_in_out intermediate results may be returned + * even though it may be invalid. + * + * RETURNS + * XcmsFailure - Failure + * XcmsSuccess - Succeeded + * + */ +{ + Status retval; + XcmsCCCRec myCCC; + XcmsColor *pColor; + XcmsColor Lab_max; + XcmsFloat hue, chroma, maxChroma; + XcmsFloat Chroma, bestChroma, Lstar, maxLstar, saveLstar; + XcmsFloat bestLstar, bestastar, bestbstar; + XcmsFloat nT, saveDist, tmpDist; + XcmsRGBi rgb_max; + int nCount, nMaxCount, nI, nILast; + + /* Use my own CCC */ + memcpy ((char *)&myCCC, (char *)ccc, sizeof(XcmsCCCRec)); + myCCC.clientWhitePt.format = XcmsUndefinedFormat;/* inherit screen white */ + myCCC.gamutCompProc = (XcmsCompressionProc)NULL;/* no gamut compression func */ + + /* + * Color specification passed as input can be assumed to: + * 1. Be in XcmsCIEXYZFormat + * 2. Already be white point adjusted for the Screen White Point. + * This means that the white point now associated with this + * color spec is the Screen White Point (even if the + * ccc->clientWhitePt differs). + */ + + pColor = pColors_in_out + i; + + if (ccc->visual->class < StaticColor) { + /* + * GRAY ! + */ + _XcmsDIConvertColors(ccc, pColor, ScreenWhitePointOfCCC(ccc), + 1, XcmsCIELabFormat); + _XcmsDIConvertColors(ccc, pColor, ScreenWhitePointOfCCC(ccc), + 1, XcmsCIEXYZFormat); + if (pCompressed) { + *(pCompressed + i) = True; + } + return(XcmsSuccess); + } + + /* Convert from CIEXYZ to CIELab format */ + if (_XcmsDIConvertColors(&myCCC, pColor, + ScreenWhitePointOfCCC(&myCCC), 1, XcmsCIELabFormat) + == XcmsFailure) { + return(XcmsFailure); + } + + /* Step 1: compute the maximum L* and chroma for this hue. */ + /* This copy may be overkill but it preserves the pixel etc. */ + saveLstar = pColor->spec.CIELab.L_star; + hue = XCMS_CIELAB_PMETRIC_HUE(pColor->spec.CIELab.a_star, + pColor->spec.CIELab.b_star); + chroma = XCMS_CIELAB_PMETRIC_CHROMA(pColor->spec.CIELab.a_star, + pColor->spec.CIELab.b_star); + memcpy((char *)&Lab_max, (char *)pColor, sizeof(XcmsColor)); + if (_XcmsCIELabQueryMaxLCRGB (&myCCC, hue, &Lab_max, &rgb_max) + == XcmsFailure) { + return (XcmsFailure); + } + maxLstar = Lab_max.spec.CIELab.L_star; + + /* Now check and return the appropriate L* */ + if (saveLstar == maxLstar) { + /* When the L* input is equal to the maximum L* */ + /* merely return the maximum Lab point. */ + memcpy((char *)pColor, (char *)&Lab_max, sizeof(XcmsColor)); + retval = _XcmsDIConvertColors(&myCCC, pColor, + ScreenWhitePointOfCCC(&myCCC), 1, XcmsCIEXYZFormat); + } else { + /* return the closest point on the hue leaf. */ + /* must do a bisection here to compute the delta e. */ + maxChroma = XCMS_CIELAB_PMETRIC_CHROMA(Lab_max.spec.CIELab.a_star, + Lab_max.spec.CIELab.b_star); + nMaxCount = MAXBISECTCOUNT; + nI = nMaxCount / 2; + bestLstar = Lstar = pColor->spec.CIELab.L_star; + bestastar = pColor->spec.CIELab.a_star; + bestbstar = pColor->spec.CIELab.b_star; + bestChroma = Chroma = chroma; + saveDist = XCMS_SQRT(((Chroma - maxChroma) * (Chroma - maxChroma)) + + ((Lstar - maxLstar) * (Lstar - maxLstar))); + for (nCount = 0; nCount < nMaxCount; nCount++) { + nT = (XcmsFloat) nI / (XcmsFloat) nMaxCount; + if (saveLstar > maxLstar) { + pColor->spec.RGBi.red = rgb_max.red * (1.0 - nT) + nT; + pColor->spec.RGBi.green = rgb_max.green * (1.0 - nT) + nT; + pColor->spec.RGBi.blue = rgb_max.blue * (1.0 - nT) + nT; + } else { + pColor->spec.RGBi.red = rgb_max.red - (rgb_max.red * nT); + pColor->spec.RGBi.green = rgb_max.green - (rgb_max.green * nT); + pColor->spec.RGBi.blue = rgb_max.blue - (rgb_max.blue * nT); + } + pColor->format = XcmsRGBiFormat; + + /* Convert from RGBi to CIE Lab */ + if (_XcmsConvertColorsWithWhitePt(&myCCC, pColor, + ScreenWhitePointOfCCC(&myCCC), 1, XcmsCIELabFormat, + (Bool *) NULL) == XcmsFailure) { + return (XcmsFailure); + } + chroma = XCMS_CIELAB_PMETRIC_CHROMA(pColor->spec.CIELab.a_star, + pColor->spec.CIELab.b_star); + tmpDist = XCMS_SQRT(((Chroma - chroma) * (Chroma - chroma)) + + ((Lstar - pColor->spec.CIELab.L_star) * + (Lstar - pColor->spec.CIELab.L_star))); + nILast = nI; + if (tmpDist > saveDist) { + nI /= 2; + } else { + nI = (nMaxCount + nI) / 2; + saveDist = tmpDist; + bestLstar = pColor->spec.CIELab.L_star; + bestastar = pColor->spec.CIELab.a_star; + bestbstar = pColor->spec.CIELab.b_star; + bestChroma = chroma; + } + if (nI == nILast || nI == 0) { + break; + } + } + if (bestChroma >= maxChroma) { + pColor->spec.CIELab.L_star = maxLstar; + pColor->spec.CIELab.a_star = Lab_max.spec.CIELab.a_star; + pColor->spec.CIELab.b_star = Lab_max.spec.CIELab.b_star; + } else { + pColor->spec.CIELab.L_star = bestLstar; + pColor->spec.CIELab.a_star = bestastar; + pColor->spec.CIELab.b_star = bestbstar; + } + retval = _XcmsDIConvertColors(&myCCC, pColor, + ScreenWhitePointOfCCC(&myCCC), 1, XcmsCIEXYZFormat); + + if (retval != XcmsFailure && pCompressed != NULL) { + *(pCompressed + i) = True; + } + } + return(retval); +} diff --git a/src/xcms/LabMnL.c b/src/xcms/LabMnL.c new file mode 100644 index 00000000..c5ca3e8e --- /dev/null +++ b/src/xcms/LabMnL.c @@ -0,0 +1,218 @@ +/* $Xorg: LabMnL.c,v 1.3 2000/08/17 19:44:39 cpqbld Exp $ */ + +/* + * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. + * All Rights Reserved + * + * This file is a component of an X Window System-specific implementation + * of XCMS based on the TekColor Color Management System. Permission is + * hereby granted to use, copy, modify, sell, and otherwise distribute this + * software and its documentation for any purpose and without fee, provided + * that this copyright, permission, and disclaimer notice is reproduced in + * all copies of this software and in supporting documentation. TekColor + * is a trademark of Tektronix, Inc. + * + * Tektronix makes no representation about the suitability of this software + * for any purpose. It is provided "as is" and with all faults. + * + * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, + * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX 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 THE PERFORMANCE OF THIS SOFTWARE. + * + * NAME + * CIELabMnL.c + * + * DESCRIPTION + * Source for the XcmsCIELabQueryMinL() gamut boundary + * querying routine. + * + */ + +#include "Xlibint.h" +#include "Xcmsint.h" +#include <math.h> + +/* + * DEFINES + */ +#define MAXBISECTCOUNT 100 +#define EPS (XcmsFloat)0.001 +#define START_L_STAR (XcmsFloat)40.0 + +/* + * EXTERNS + */ +extern Status _XcmsCIELabQueryMaxLCRGB(); + + +/************************************************************************ + * * + * PUBLIC ROUTINES * + * * + ************************************************************************/ + +/* + * NAME + * XcmsCIELabQueryMinL - Compute max Lstar for a hue and chroma + * + * SYNOPSIS + */ +Status +XcmsCIELabQueryMinL(ccc, hue_angle, chroma, pColor_return) + XcmsCCC ccc; + XcmsFloat hue_angle; /* hue angle in degrees */ + XcmsFloat chroma; + XcmsColor *pColor_return; +/* + * DESCRIPTION + * Return the maximum Lstar for a specified hue_angle and chroma. + * + * ASSUMPTIONS + * This routine assumes that the white point associated with + * the color specification is the Screen White Point. The + * Screen White Point will also be associated with the + * returned color specification. + * + * RETURNS + * XcmsFailure - Failure + * XcmsSuccess - Succeeded with no modifications + * + */ +{ + XcmsCCCRec myCCC; + XcmsColor max_lc, tmp, prev; + XcmsFloat max_chroma, tmp_chroma; + XcmsFloat hue, nT, nChroma, lastChroma, prevChroma; + XcmsFloat rFactor; + XcmsRGBi rgb_saved; + int nCount, nMaxCount; + + /* + * Check Arguments + */ + if (ccc == NULL || pColor_return == NULL) { + return(XcmsFailure); + } + + /* setup the CCC to use for the conversions. */ + memcpy ((char *) &myCCC, (char *) ccc, sizeof(XcmsCCCRec)); + myCCC.clientWhitePt.format = XcmsUndefinedFormat; + myCCC.gamutCompProc = (XcmsCompressionProc) NULL; + + while (hue_angle < 0.0) { + hue_angle += 360.0; + } + while (hue_angle >= 360.0) { + hue_angle -= 360.0; + } + + hue = radians(hue_angle); + tmp.spec.CIELab.L_star = START_L_STAR; + tmp.spec.CIELab.a_star = XCMS_CIEASTAROFHUE(hue, chroma); + tmp.spec.CIELab.b_star = XCMS_CIEBSTAROFHUE(hue, chroma); + tmp.pixel = pColor_return->pixel; + tmp.format = XcmsCIELabFormat; + + /* Step 1: Obtain the maximum L_star and chroma for this hue. */ + if (_XcmsCIELabQueryMaxLCRGB(&myCCC, hue, &max_lc, &rgb_saved) + == XcmsFailure) { + return(XcmsFailure); + } + + max_chroma = XCMS_CIELAB_PMETRIC_CHROMA(max_lc.spec.CIELab.a_star, + max_lc.spec.CIELab.b_star); + + if (max_chroma <= chroma) { + /* + * If the chroma is greater than the chroma for the + * maximum L/chroma point then the L_star is the + * the L_star for the maximum L_star/chroma point. + * This is an error but I return the best approximation I can. + * Thus the inconsistency. + */ + memcpy ((char *) pColor_return, (char *) &max_lc, sizeof (XcmsColor)); + return(XcmsSuccess); + } + + /* + * If the chroma is equal to the chroma for the + * maximum L_star/chroma point then the L_star is the + * the L_star for the maximum L* and chroma point. + */ + /* if (max_chroma == chroma) { + * memcpy ((char *) pColor_return, (char *) &max_lc, sizeof (XcmsColor)); + * return(XcmsSuccess); + * } + */ + + /* must do a bisection here to compute the maximum L* */ + /* save the structure input so that any elements that */ + /* are not touched are recopied later in the routine. */ + nChroma = chroma; + tmp_chroma = max_chroma; + lastChroma = -1.0; + nMaxCount = MAXBISECTCOUNT; + rFactor = 1.0; + + for (nCount = 0; nCount < nMaxCount; nCount++) { + prevChroma = lastChroma; + lastChroma = tmp_chroma; + nT = (nChroma - max_chroma) / max_chroma * rFactor; + memcpy ((char *)&prev, (char *)&tmp, sizeof(XcmsColor)); + tmp.spec.RGBi.red = rgb_saved.red + (rgb_saved.red * nT); + tmp.spec.RGBi.green = rgb_saved.green + (rgb_saved.green * nT); + tmp.spec.RGBi.blue = rgb_saved.blue + (rgb_saved.blue * nT); + tmp.format = XcmsRGBiFormat; + + /* convert from RGB to CIELab */ + if (_XcmsConvertColorsWithWhitePt(&myCCC, &tmp, + ScreenWhitePointOfCCC(&myCCC), 1, XcmsCIELabFormat, + (Bool *) NULL) == XcmsFailure) { + return(XcmsFailure); + } + + /* Now check the return against what is expected */ + tmp_chroma = XCMS_CIELAB_PMETRIC_CHROMA(tmp.spec.CIELab.a_star, + tmp.spec.CIELab.b_star); + if (tmp_chroma <= chroma + EPS && tmp_chroma >= chroma - EPS) { + /* Found It! */ + memcpy ((char *) pColor_return, (char *) &tmp, sizeof (XcmsColor)); + return(XcmsSuccess); + } + nChroma += chroma - tmp_chroma; + if (nChroma > max_chroma) { + nChroma = max_chroma; + rFactor *= 0.5; /* selective relaxation employed */ + } else if (nChroma < 0.0) { + if (XCMS_FABS(lastChroma - chroma) < + XCMS_FABS(tmp_chroma - chroma)) { + memcpy ((char *)pColor_return, (char *)&prev, + sizeof(XcmsColor)); + } else { + memcpy ((char *)pColor_return, (char *)&tmp, + sizeof(XcmsColor)); + } + return(XcmsSuccess); + } else if (tmp_chroma <= prevChroma + EPS && + tmp_chroma >= prevChroma - EPS) { + rFactor *= 0.5; /* selective relaxation employed */ + } + } + + if (nCount >= nMaxCount) { + if (XCMS_FABS(lastChroma - chroma) < + XCMS_FABS(tmp_chroma - chroma)) { + memcpy ((char *)pColor_return, (char *)&prev, + sizeof(XcmsColor)); + } else { + memcpy ((char *)pColor_return, (char *)&tmp, + sizeof(XcmsColor)); + } + } + memcpy ((char *) pColor_return, (char *) &tmp, sizeof (XcmsColor)); + return(XcmsSuccess); +} diff --git a/src/xcms/LabMxC.c b/src/xcms/LabMxC.c new file mode 100644 index 00000000..a1a3d69d --- /dev/null +++ b/src/xcms/LabMxC.c @@ -0,0 +1,205 @@ +/* $Xorg: LabMxC.c,v 1.3 2000/08/17 19:44:40 cpqbld Exp $ */ + +/* + * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. + * All Rights Reserved + * + * This file is a component of an X Window System-specific implementation + * of XCMS based on the TekColor Color Management System. Permission is + * hereby granted to use, copy, modify, sell, and otherwise distribute this + * software and its documentation for any purpose and without fee, provided + * that this copyright, permission, and disclaimer notice is reproduced in + * all copies of this software and in supporting documentation. TekColor + * is a trademark of Tektronix, Inc. + * + * Tektronix makes no representation about the suitability of this software + * for any purpose. It is provided "as is" and with all faults. + * + * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, + * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX 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 THE PERFORMANCE OF THIS SOFTWARE. + * + * + * + * NAME + * CIELabMxC.c + * + * DESCRIPTION + * Source for the XcmsCIELabQueryMaxC() gamut boundary + * querying routine. + * + */ + +#include "Xlibint.h" +#include "Xcmsint.h" +#include <math.h> + +/* + * DEFINES + */ +#define MAXBISECTCOUNT 100 +#define EPS (XcmsFloat)0.001 +#define START_CHROMA (XcmsFloat)3.6 +#define TOPL (XcmsFloat)100.0 + +/* + * EXTERNS + */ +extern Status _XcmsCIELabQueryMaxLCRGB(); + + +/************************************************************************ + * * + * PUBLIC ROUTINES * + * * + ************************************************************************/ + +/* + * NAME + * XcmsCIELabQueryMaxC - max chroma for a hue_angle and L_star + * + * SYNOPSIS + */ +Status +XcmsCIELabQueryMaxC(ccc, hue_angle, L_star, pColor_return) + XcmsCCC ccc; + XcmsFloat hue_angle; /* hue angle in degrees */ + XcmsFloat L_star; + XcmsColor *pColor_return; +/* + * DESCRIPTION + * Return the maximum chroma for a specific hue_angle and L_star. + * The returned format is in XcmsCIELabFormat. + * + * + * ASSUMPTIONS + * This routine assumes that the white point associated with + * the color specification is the Screen White Point. The + * Screen White Point will also be associated with the + * returned color specification. + * + * RETURNS + * XcmsFailure - Failure + * XcmsSuccess - Succeeded + * + */ +{ + XcmsCCCRec myCCC; + XcmsColor tmp; + XcmsColor max_lc; + XcmsFloat n_L_star, last_L_star, prev_L_star; + XcmsFloat hue, lastaStar, lastbStar, /*lastChroma,*/ maxDist, nT, rFactor; + XcmsRGBi rgb_saved; + int nCount, nMaxCount; + + /* + * Check Arguments + */ + if (ccc == NULL || pColor_return == NULL) { + return(XcmsFailure); + } + + /* Use my own CCC and inherit screen white Pt */ + memcpy ((char *)&myCCC, (char *)ccc, sizeof(XcmsCCCRec)); + myCCC.clientWhitePt.format = XcmsUndefinedFormat; + myCCC.gamutCompProc = (XcmsCompressionProc)NULL;/* no gamut comp func */ + + while (hue_angle < 0.0) { + hue_angle += 360.0; + } + while (hue_angle >= 360.0) { + hue_angle -= 360.0; + } + + hue = radians(hue_angle); + tmp.spec.CIELab.L_star = L_star; + tmp.spec.CIELab.a_star = XCMS_CIEASTAROFHUE(hue, START_CHROMA); + tmp.spec.CIELab.b_star = XCMS_CIEBSTAROFHUE(hue, START_CHROMA); + tmp.pixel = pColor_return->pixel; + tmp.format = XcmsCIELabFormat; + + /* Step 1: compute the maximum L_star and chroma for this hue. */ + memcpy((char *)&max_lc, (char *)&tmp, sizeof(XcmsColor)); + if (_XcmsCIELabQueryMaxLCRGB(&myCCC, hue, &max_lc, &rgb_saved) + == XcmsFailure) { + return(XcmsFailure); + } + + /* + * Step 2: Do a bisection here to compute the maximum chroma + * Note the differences between when the point to be found + * is above the maximum LC point and when it is below. + */ + if (L_star <= max_lc.spec.CIELab.L_star) { + maxDist = max_lc.spec.CIELab.L_star; + } else { + maxDist = TOPL - max_lc.spec.CIELab.L_star; + } + + n_L_star = L_star; + last_L_star = -1.0; + nMaxCount = MAXBISECTCOUNT; + rFactor = 1.0; + + for (nCount = 0; nCount < nMaxCount; nCount++) { + prev_L_star = last_L_star; + last_L_star = tmp.spec.CIELab.L_star; +/* lastChroma = XCMS_CIELAB_PMETRIC_CHROMA(tmp.spec.CIELab.a_star, */ +/* tmp.spec.CIELab.b_star); */ + lastaStar = tmp.spec.CIELab.a_star; + lastbStar = tmp.spec.CIELab.b_star; + nT = (n_L_star - max_lc.spec.CIELab.L_star) / maxDist * rFactor; + if (nT > 0) { + tmp.spec.RGBi.red = rgb_saved.red * (1.0 - nT) + nT; + tmp.spec.RGBi.green = rgb_saved.green * (1.0 - nT) + nT; + tmp.spec.RGBi.blue = rgb_saved.blue * (1.0 - nT) + nT; + } else { + tmp.spec.RGBi.red = rgb_saved.red + (rgb_saved.red * nT); + tmp.spec.RGBi.green = rgb_saved.green + (rgb_saved.green * nT); + tmp.spec.RGBi.blue = rgb_saved.blue + (rgb_saved.blue * nT); + } + tmp.format = XcmsRGBiFormat; + + /* convert from RGB to CIELab */ + if (_XcmsConvertColorsWithWhitePt(&myCCC, &tmp, + ScreenWhitePointOfCCC(&myCCC), 1, XcmsCIELabFormat, + (Bool *) NULL) == XcmsFailure) { + return(XcmsFailure); + } + + /* + * Now check if we've reached the target L_star + */ + /* printf("result Lstar = %lf\n", tmp.spec.CIELab.L_star); */ + if (tmp.spec.CIELab.L_star <= L_star + EPS && + tmp.spec.CIELab.L_star >= L_star - EPS) { + memcpy((char *)pColor_return, (char *)&tmp, sizeof(XcmsColor)); + return(XcmsSuccess); + } + if (nT > 0) { + n_L_star += ((TOPL - n_L_star) * + (L_star - tmp.spec.CIELab.L_star)) / (TOPL - L_star); + } else { + n_L_star *= L_star / tmp.spec.CIELuv.L_star; + } + if (tmp.spec.CIELab.L_star <= prev_L_star + EPS && + tmp.spec.CIELab.L_star >= prev_L_star - EPS) { + rFactor *= 0.5; /* selective relaxation employed */ + /* printf("rFactor = %lf\n", rFactor); */ + } + } + if (XCMS_FABS(last_L_star - L_star) < + XCMS_FABS(tmp.spec.CIELab.L_star - L_star)) { + tmp.spec.CIELab.a_star = lastaStar; + tmp.spec.CIELab.b_star = lastbStar; +/* tmp.spec.CIELab.a_star = XCMS_CIEASTAROFHUE(hue, lastChroma); */ +/* tmp.spec.CIELab.b_star = XCMS_CIEBSTAROFHUE(hue, lastChroma); */ + } + tmp.spec.CIELab.L_star = L_star; + memcpy((char *)pColor_return, (char *)&tmp, sizeof(XcmsColor)); + return(XcmsSuccess); +} diff --git a/src/xcms/LabMxL.c b/src/xcms/LabMxL.c new file mode 100644 index 00000000..a31a8f41 --- /dev/null +++ b/src/xcms/LabMxL.c @@ -0,0 +1,218 @@ +/* $Xorg: LabMxL.c,v 1.3 2000/08/17 19:44:40 cpqbld Exp $ */ + +/* + * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. + * All Rights Reserved + * + * This file is a component of an X Window System-specific implementation + * of XCMS based on the TekColor Color Management System. Permission is + * hereby granted to use, copy, modify, sell, and otherwise distribute this + * software and its documentation for any purpose and without fee, provided + * that this copyright, permission, and disclaimer notice is reproduced in + * all copies of this software and in supporting documentation. TekColor + * is a trademark of Tektronix, Inc. + * + * Tektronix makes no representation about the suitability of this software + * for any purpose. It is provided "as is" and with all faults. + * + * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, + * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX 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 THE PERFORMANCE OF THIS SOFTWARE. + * + * NAME + * CIELabMxL.c + * + * DESCRIPTION + * Source for the XcmsCIELabQueryMaxL() gamut boundary + * querying routine. + * + */ + +#include "Xlibint.h" +#include "Xcmsint.h" +#include <math.h> + +/* + * DEFINES + */ +#define MAXBISECTCOUNT 100 +#define EPS (XcmsFloat)0.001 +#define START_L_STAR (XcmsFloat)40 + +/* + * EXTERNS + */ +extern Status _XcmsCIELabQueryMaxLCRGB(); + + +/************************************************************************ + * * + * PUBLIC ROUTINES * + * * + ************************************************************************/ + +/* + * NAME + * XcmsCIELabQueryMaxL - Compute max Lstar for a hue and chroma + * + * SYNOPSIS + */ +Status +XcmsCIELabQueryMaxL(ccc, hue_angle, chroma, pColor_return) + XcmsCCC ccc; + XcmsFloat hue_angle; /* hue in degrees */ + XcmsFloat chroma; + XcmsColor *pColor_return; +/* + * DESCRIPTION + * Return the maximum Lstar for a specified hue_angle and chroma. + * + * ASSUMPTIONS + * This routine assumes that the white point associated with + * the color specification is the Screen White Point. The + * Screen White Point will also be associated with the + * returned color specification. + * + * RETURNS + * XcmsFailure - Failure + * XcmsSuccess - Succeeded with no modifications + * + */ +{ + XcmsCCCRec myCCC; + XcmsColor max_lc, tmp, prev; + XcmsFloat max_chroma, tmp_chroma; + XcmsFloat hue, nT, nChroma, lastChroma, prevChroma; + XcmsFloat rFactor; + XcmsRGBi rgb_saved; + int nCount, nMaxCount; + + /* + * Check Arguments + */ + if (ccc == NULL || pColor_return == NULL) { + return(XcmsFailure); + } + + /* setup the CCC to use for the conversions. */ + memcpy ((char *) &myCCC, (char *) ccc, sizeof(XcmsCCCRec)); + myCCC.clientWhitePt.format = XcmsUndefinedFormat; + myCCC.gamutCompProc = (XcmsCompressionProc) NULL; + + while (hue_angle < 0.0) { + hue_angle += 360.0; + } + while (hue_angle >= 360.0) { + hue_angle -= 360.0; + } + + hue = radians(hue_angle); + tmp.spec.CIELab.L_star = START_L_STAR; + tmp.spec.CIELab.a_star = XCMS_CIEASTAROFHUE(hue, chroma); + tmp.spec.CIELab.b_star = XCMS_CIEBSTAROFHUE(hue, chroma); + tmp.pixel = pColor_return->pixel; + tmp.format = XcmsCIELabFormat; + + /* Step 1: Obtain the maximum L_star and chroma for this hue. */ + if (_XcmsCIELabQueryMaxLCRGB(&myCCC, hue, &max_lc, &rgb_saved) + == XcmsFailure) { + return(XcmsFailure); + } + + max_chroma = XCMS_CIELAB_PMETRIC_CHROMA(max_lc.spec.CIELab.a_star, + max_lc.spec.CIELab.b_star); + + if (max_chroma <= chroma) { + /* + * If the chroma is greater than the chroma for the + * maximum L/chroma point then the L_star is the + * the L_star for the maximum L_star/chroma point. + * This is an error but I return the best approximation I can. + * Thus the inconsistency. + */ + memcpy ((char *) pColor_return, (char *) &max_lc, sizeof (XcmsColor)); + return(XcmsSuccess); + } + + /* + * If the chroma is equal to the chroma for the + * maximum L_star/chroma point then the L_star is the + * the L_star for the maximum L* and chroma point. + */ + /* if (max_chroma == chroma) { + * memcpy ((char *) pColor_return, (char *) &max_lc, sizeof (XcmsColor)); + * return(XcmsSuccess); + * } + */ + + /* must do a bisection here to compute the maximum L* */ + /* save the structure input so that any elements that */ + /* are not touched are recopied later in the routine. */ + nChroma = chroma; + tmp_chroma = max_chroma; + lastChroma = -1.0; + nMaxCount = MAXBISECTCOUNT; + rFactor = 1.0; + + for (nCount = 0; nCount < nMaxCount; nCount++) { + prevChroma = lastChroma; + lastChroma = tmp_chroma; + nT = (1.0 - (nChroma / max_chroma)) * rFactor; + memcpy ((char *)&prev, (char *)&tmp, sizeof(XcmsColor)); + tmp.spec.RGBi.red = rgb_saved.red * (1.0 - nT) + nT; + tmp.spec.RGBi.green = rgb_saved.green * (1.0 - nT) + nT; + tmp.spec.RGBi.blue = rgb_saved.blue * (1.0 - nT) + nT; + tmp.format = XcmsRGBiFormat; + + /* convert from RGB to CIELab */ + if (_XcmsConvertColorsWithWhitePt(&myCCC, &tmp, + ScreenWhitePointOfCCC(&myCCC), 1, XcmsCIELabFormat, + (Bool *) NULL) == XcmsFailure) { + return(XcmsFailure); + } + + /* Now check the return against what is expected */ + tmp_chroma = XCMS_CIELAB_PMETRIC_CHROMA(tmp.spec.CIELab.a_star, + tmp.spec.CIELab.b_star); + if (tmp_chroma <= chroma + EPS && tmp_chroma >= chroma - EPS) { + /* Found It! */ + memcpy ((char *) pColor_return, (char *) &tmp, sizeof (XcmsColor)); + return(XcmsSuccess); + } + nChroma += chroma - tmp_chroma; + if (nChroma > max_chroma) { + nChroma = max_chroma; + rFactor *= 0.5; /* selective relaxation employed */ + } else if (nChroma < 0.0) { + if (XCMS_FABS(lastChroma - chroma) < + XCMS_FABS(tmp_chroma - chroma)) { + memcpy ((char *)pColor_return, (char *)&prev, + sizeof(XcmsColor)); + } else { + memcpy ((char *)pColor_return, (char *)&tmp, + sizeof(XcmsColor)); + } + return(XcmsSuccess); + } else if (tmp_chroma <= prevChroma + EPS && + tmp_chroma >= prevChroma - EPS) { + rFactor *= 0.5; /* selective relaxation employed */ + } + } + + if (nCount >= nMaxCount) { + if (XCMS_FABS(lastChroma - chroma) < + XCMS_FABS(tmp_chroma - chroma)) { + memcpy ((char *)pColor_return, (char *)&prev, + sizeof(XcmsColor)); + } else { + memcpy ((char *)pColor_return, (char *)&tmp, + sizeof(XcmsColor)); + } + } + memcpy ((char *) pColor_return, (char *) &tmp, sizeof (XcmsColor)); + return(XcmsSuccess); +} diff --git a/src/xcms/LabMxLC.c b/src/xcms/LabMxLC.c new file mode 100644 index 00000000..6fdeeb1b --- /dev/null +++ b/src/xcms/LabMxLC.c @@ -0,0 +1,226 @@ +/* $Xorg: LabMxLC.c,v 1.3 2000/08/17 19:44:40 cpqbld Exp $ */ + +/* + * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. + * All Rights Reserved + * + * This file is a component of an X Window System-specific implementation + * of XCMS based on the TekColor Color Management System. Permission is + * hereby granted to use, copy, modify, sell, and otherwise distribute this + * software and its documentation for any purpose and without fee, provided + * that this copyright, permission, and disclaimer notice is reproduced in + * all copies of this software and in supporting documentation. TekColor + * is a trademark of Tektronix, Inc. + * + * Tektronix makes no representation about the suitability of this software + * for any purpose. It is provided "as is" and with all faults. + * + * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, + * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX 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 THE PERFORMANCE OF THIS SOFTWARE. + * + * + * + * NAME + * CIELabMxVC.c + * + * DESCRIPTION + * Source for the XcmsCIELabQueryMaxLC() gamut boundary + * querying routine. + * + * DOCUMENTATION + * "TekColor Color Management System, System Implementor's Manual" + * and + * Fred W. Billmeyer & Max Saltzman, "Principles of Color + * Technology", John Wily & Sons, Inc, 1981. + */ + +#include "Xlibint.h" +#include "Xcmsint.h" + +/* + * DEFINES + */ +#define MIN(x,y) ((x) > (y) ? (y) : (x)) +#define MIN3(x,y,z) ((x) > (MIN((y), (z))) ? (MIN((y), (z))) : (x)) +#define MAX(x,y) ((x) > (y) ? (x) : (y)) +#define MAX3(x,y,z) ((x) > (MAX((y), (z))) ? (x) : (MAX((y), (z)))) +#define START_LSTAR (XcmsFloat)40.0 +#define START_CHROMA (XcmsFloat)3.6 + +/* + * EXTERNS + */ +extern Status _XcmsConvertColorsWithWhitePt(); + +/* + * FORWARD DECLARATIONS + */ +Status _XcmsCIELabQueryMaxLCRGB(); + + +/************************************************************************ + * * + * API PRIVATE ROUTINES * + * * + ************************************************************************/ + +/* + * NAME + * _XcmsCIELabQueryMaxLCRGB - Compute maximum L* and chroma. + * + * SYNOPSIS + */ +Status +_XcmsCIELabQueryMaxLCRGB(ccc, hue, pColor_return, pRGB_return) + XcmsCCC ccc; + XcmsFloat hue; /* hue in radians */ + XcmsColor *pColor_return; + XcmsRGBi *pRGB_return; + +/* + * DESCRIPTION + * Return the maximum psychometric chroma for a specified + * hue, and the corresponding L*. This is computed + * by a binary search of all possible chromas. An assumption + * is made that there are no local maxima. Use the unrounded + * Max psychometric chroma because the difference check can be + * small. + * + * NOTE: No local CCC is used because this is a private + * routine and all routines that call it are expected + * to behave properly, i.e. send a local CCC with + * no white adjust function and no gamut compression + * function. + * + * This routine only accepts hue in radians as input and outputs + * Lab and RGBi. + * + * RETURNS + * XcmsFailure - Failure + * XcmsSuccess - Succeeded + * + */ +{ + XcmsFloat nSmall, nLarge; + XcmsColor tmp; + + tmp.format = XcmsCIELabFormat; + /* Use some unreachable color on the given hue */ + tmp.spec.CIELab.L_star = START_LSTAR; + tmp.spec.CIELab.a_star = XCMS_CIEASTAROFHUE(hue, START_CHROMA); + tmp.spec.CIELab.b_star = XCMS_CIEBSTAROFHUE(hue, START_CHROMA); + /* + * Convert from Lab to RGB + * + * Note that the CIEXYZ to RGBi conversion routine must stuff the + * out of bounds RGBi values in tmp when the ccc->gamutCompProc + * is NULL. + */ + if ((_XcmsConvertColorsWithWhitePt(ccc, &tmp, ScreenWhitePointOfCCC(ccc), + (unsigned int)1, XcmsRGBiFormat, (Bool *) NULL) + == XcmsFailure) && tmp.format != XcmsRGBiFormat) { + return (XcmsFailure); + } + + /* Now pick the smallest RGB */ + nSmall = MIN3(tmp.spec.RGBi.red, + tmp.spec.RGBi.green, + tmp.spec.RGBi.blue); + /* Make the smallest RGB equal to zero */ + tmp.spec.RGBi.red -= nSmall; + tmp.spec.RGBi.green -= nSmall; + tmp.spec.RGBi.blue -= nSmall; + + /* Now pick the largest RGB */ + nLarge = MAX3(tmp.spec.RGBi.red, + tmp.spec.RGBi.green, + tmp.spec.RGBi.blue); + /* Scale the RGB values based on the largest one */ + tmp.spec.RGBi.red /= nLarge; + tmp.spec.RGBi.green /= nLarge; + tmp.spec.RGBi.blue /= nLarge; + tmp.format = XcmsRGBiFormat; + + /* If the calling routine wants RGB value give them the ones used. */ + if (pRGB_return) { + pRGB_return->red = tmp.spec.RGBi.red; + pRGB_return->green = tmp.spec.RGBi.green; + pRGB_return->blue = tmp.spec.RGBi.blue; + } + + /* Convert from RGBi to Lab */ + if (_XcmsConvertColorsWithWhitePt(ccc, &tmp, + ScreenWhitePointOfCCC(ccc), 1, XcmsCIELabFormat, (Bool *) NULL) + == XcmsFailure) { + return (XcmsFailure); + } + + memcpy((char *)pColor_return, (char *)&tmp, sizeof(XcmsColor)); + return (XcmsSuccess); +} + + +/************************************************************************ + * * + * PUBLIC ROUTINES * + * * + ************************************************************************/ + +/* + * NAME + * XcmsCIELabQueryMaxLC - Compute maximum L* and chroma. + * + * SYNOPSIS + */ +Status +XcmsCIELabQueryMaxLC (ccc, hue_angle, pColor_return) + XcmsCCC ccc; + XcmsFloat hue_angle; /* hue_angle in degrees */ + XcmsColor *pColor_return; + +/* + * DESCRIPTION + * Return the point of maximum chroma for the specified + * hue_angle. + * + * ASSUMPTIONS + * This routine assumes that the white point associated with + * the color specification is the Screen White Point. The + * Screen White Point will also be associated with the + * returned color specification. + * + * RETURNS + * XcmsFailure - Failure + * XcmsSuccess - Succeeded + * + */ +{ + XcmsCCCRec myCCC; + + /* + * Check Arguments + */ + if (ccc == NULL || pColor_return == NULL) { + return(XcmsFailure); + } + + /* Use my own CCC */ + memcpy ((char *)&myCCC, (char *)ccc, sizeof(XcmsCCCRec)); + myCCC.clientWhitePt.format = XcmsUndefinedFormat; + myCCC.gamutCompProc = (XcmsCompressionProc)NULL; + + while (hue_angle < 0.0) { + hue_angle += 360.0; + } + while (hue_angle >= 360.0) { + hue_angle -= 360.0; + } + + return(_XcmsCIELabQueryMaxLCRGB (&myCCC, radians(hue_angle), pColor_return, + (XcmsRGBi *)NULL)); +} diff --git a/src/xcms/LabWpAj.c b/src/xcms/LabWpAj.c new file mode 100644 index 00000000..b4fc4a32 --- /dev/null +++ b/src/xcms/LabWpAj.c @@ -0,0 +1,97 @@ +/* $Xorg: LabWpAj.c,v 1.3 2000/08/17 19:44:40 cpqbld Exp $ */ + +/* + * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. + * All Rights Reserved + * + * This file is a component of an X Window System-specific implementation + * of XCMS based on the TekColor Color Management System. Permission is + * hereby granted to use, copy, modify, sell, and otherwise distribute this + * software and its documentation for any purpose and without fee, provided + * that this copyright, permission, and disclaimer notice is reproduced in + * all copies of this software and in supporting documentation. TekColor + * is a trademark of Tektronix, Inc. + * + * Tektronix makes no representation about the suitability of this software + * for any purpose. It is provided "as is" and with all faults. + * + * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, + * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX 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 THE PERFORMANCE OF THIS SOFTWARE. + * + * + * NAME + * CIELabWpAj.c + * + * DESCRIPTION + * This file contains routine(s) that support white point + * adjustment of color specifications in the CIE L*a*b* color + * space. + */ + +#include "Xlibint.h" +#include "Xcmsint.h" + +/* + * EXTERNS + */ + +extern Status _XcmsConvertColorsWithWhitePt(); + + +/************************************************************************ + * * + * PUBLIC ROUTINES * + * * + ************************************************************************/ + +/* + * NAME + * XcmsCIELabWhiteShiftColors + * + * SYNOPSIS + */ +Status +XcmsCIELabWhiteShiftColors(ccc, pWhitePtFrom, pWhitePtTo, destSpecFmt, + pColors_in_out, nColors, pCompressed) + XcmsCCC ccc; + XcmsColor *pWhitePtFrom; + XcmsColor *pWhitePtTo; + XcmsColorFormat destSpecFmt; + XcmsColor *pColors_in_out; + unsigned int nColors; + Bool *pCompressed; +/* + * DESCRIPTION + * Adjust color specifications in XcmsColor structures for + * differences in white points. + * + * RETURNS + * XcmsFailure if failed, + * XcmsSuccess if succeeded without gamut compression, + * XcmsSuccessWithCompression if succeeded with gamut + * compression. + */ +{ + if (pWhitePtFrom == NULL || pWhitePtTo == NULL || pColors_in_out == NULL) { + return(0); + } + + /* + * Convert to CIELab using pWhitePtFrom + */ + if (_XcmsConvertColorsWithWhitePt(ccc, pColors_in_out, pWhitePtFrom, + nColors, XcmsCIELabFormat, pCompressed) == XcmsFailure) { + return(XcmsFailure); + } + + /* + * Convert from CIELab to destSpecFmt using pWhitePtTo + */ + return(_XcmsConvertColorsWithWhitePt(ccc, pColors_in_out, + pWhitePtTo, nColors, destSpecFmt, pCompressed)); +} diff --git a/src/xcms/Luv.c b/src/xcms/Luv.c new file mode 100644 index 00000000..9cb56cfd --- /dev/null +++ b/src/xcms/Luv.c @@ -0,0 +1,385 @@ +/* $Xorg: Luv.c,v 1.3 2000/08/17 19:44:41 cpqbld Exp $ */ + +/* + * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. + * All Rights Reserved + * + * This file is a component of an X Window System-specific implementation + * of XCMS based on the TekColor Color Management System. Permission is + * hereby granted to use, copy, modify, sell, and otherwise distribute this + * software and its documentation for any purpose and without fee, provided + * that this copyright, permission, and disclaimer notice is reproduced in + * all copies of this software and in supporting documentation. TekColor + * is a trademark of Tektronix, Inc. + * + * Tektronix makes no representation about the suitability of this software + * for any purpose. It is provided "as is" and with all faults. + * + * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, + * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX 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 THE PERFORMANCE OF THIS SOFTWARE. + * + * + * NAME + * CIELuv.c + * + * DESCRIPTION + * This file contains routines that support the CIE L*u*v* + * color space to include conversions to and from the CIE + * XYZ space. + * + * DOCUMENTATION + * "TekColor Color Management System, System Implementor's Manual" + * and + * Fred W. Billmeyer & Max Saltzman, "Principles of Color + * Technology", John Wily & Sons, Inc, 1981. + */ + +#include <X11/Xos.h> +#include "Xlibint.h" +#include "Xcmsint.h" + +/* + * EXTERNS + */ + +extern char _XcmsCIELuv_prefix[]; + + +/* + * FORWARD DECLARATIONS + */ + +static int CIELuv_ParseString(); +static Status XcmsCIELuv_ValidSpec(); + +/* + * DEFINES + * Internal definitions that need NOT be exported to any package + * or program using this package. + */ +#ifdef DBL_EPSILON +# define XMY_DBL_EPSILON DBL_EPSILON +#else +# define XMY_DBL_EPSILON 0.00001 +#endif + + +/* + * LOCAL VARIABLES + */ + + /* + * NULL terminated list of functions applied to get from CIELuv to CIEXYZ + */ +static XcmsConversionProc Fl_CIELuv_to_CIEXYZ[] = { + XcmsCIELuvToCIEuvY, + XcmsCIEuvYToCIEXYZ, + NULL +}; + + /* + * NULL terminated list of functions applied to get from CIEXYZ to CIELuv + */ +static XcmsConversionProc Fl_CIEXYZ_to_CIELuv[] = { + XcmsCIEXYZToCIEuvY, + XcmsCIEuvYToCIELuv, + NULL +}; + +/* + * GLOBALS + */ + + /* + * CIE Luv Color Space + */ +XcmsColorSpace XcmsCIELuvColorSpace = + { + _XcmsCIELuv_prefix, /* prefix */ + XcmsCIELuvFormat, /* id */ + CIELuv_ParseString, /* parseString */ + Fl_CIELuv_to_CIEXYZ, /* to_CIEXYZ */ + Fl_CIEXYZ_to_CIELuv, /* from_CIEXYZ */ + 1 + }; + + +/************************************************************************ + * * + * PRIVATE ROUTINES * + * * + ************************************************************************/ + +/* + * NAME + * CIELuv_ParseString + * + * SYNOPSIS + */ +static int +CIELuv_ParseString(spec, pColor) + register char *spec; + XcmsColor *pColor; +/* + * DESCRIPTION + * This routines takes a string and attempts to convert + * it into a XcmsColor structure with XcmsCIELuvFormat. + * The assumed CIELuv string syntax is: + * CIELuv:<L>/<u>/<v> + * Where L, u, and v are in string input format for floats + * consisting of: + * a. an optional sign + * b. a string of numbers possibly containing a decimal point, + * c. an optional exponent field containing an 'E' or 'e' + * followed by a possibly signed integer string. + * + * RETURNS + * 0 if failed, non-zero otherwise. + */ +{ + int n; + char *pchar; + + if ((pchar = strchr(spec, ':')) == NULL) { + return(XcmsFailure); + } + n = (int)(pchar - spec); + + /* + * Check for proper prefix. + */ + if (strncmp(spec, _XcmsCIELuv_prefix, n) != 0) { + return(XcmsFailure); + } + + /* + * Attempt to parse the value portion. + */ + if (sscanf(spec + n + 1, "%lf/%lf/%lf", + &pColor->spec.CIELuv.L_star, + &pColor->spec.CIELuv.u_star, + &pColor->spec.CIELuv.v_star) != 3) { + return(XcmsFailure); + } + pColor->format = XcmsCIELuvFormat; + pColor->pixel = 0; + return(XcmsCIELuv_ValidSpec(pColor)); +} + + +/************************************************************************ + * * + * PUBLIC ROUTINES * + * * + ************************************************************************/ + +/* + * NAME + * XcmsCIELuv_ValidSpec + * + * SYNOPSIS + */ +static Status +XcmsCIELuv_ValidSpec(pColor) + XcmsColor *pColor; +/* + * DESCRIPTION + * Checks if color specification valid for CIE L*u*v*. + * + * RETURNS + * XcmsFailure if invalid, + * XcmsSuccess if valid. + * + */ +{ + if (pColor->format != XcmsCIELuvFormat + || + (pColor->spec.CIELuv.L_star < 0.0 - XMY_DBL_EPSILON) + || + (pColor->spec.CIELuv.L_star > 100.0 + XMY_DBL_EPSILON)) { + return(XcmsFailure); + } + return(XcmsSuccess); +} + + +/* + * NAME + * XcmsCIELuvToCIEuvY - convert CIELuv to CIEuvY + * + * SYNOPSIS + */ +Status +XcmsCIELuvToCIEuvY(ccc, pLuv_WhitePt, pColors_in_out, nColors) + XcmsCCC ccc; + XcmsColor *pLuv_WhitePt; + XcmsColor *pColors_in_out; + unsigned int nColors; +/* + * DESCRIPTION + * Converts color specifications in an array of XcmsColor + * structures from CIELuv format to CIEuvY format. + * + * RETURNS + * XcmsFailure if failed, + * XcmsSuccess if succeeded. + * + */ +{ + XcmsColor *pColor = pColors_in_out; + XcmsColor whitePt; + XcmsCIEuvY uvY_return; + XcmsFloat tmpVal; + register int i; + + /* + * Check arguments + */ + if (pLuv_WhitePt == NULL || pColors_in_out == NULL) { + return(XcmsFailure); + } + + /* + * Make sure white point is in CIEuvY form + */ + if (pLuv_WhitePt->format != XcmsCIEuvYFormat) { + /* Make copy of the white point because we're going to modify it */ + memcpy((char *)&whitePt, (char *)pLuv_WhitePt, sizeof(XcmsColor)); + if (!_XcmsDIConvertColors(ccc, &whitePt, (XcmsColor *)NULL, + 1, XcmsCIEuvYFormat)) { + return(XcmsFailure); + } + pLuv_WhitePt = &whitePt; + } + /* Make sure it is a white point, i.e., Y == 1.0 */ + if (pLuv_WhitePt->spec.CIEuvY.Y != 1.0) { + return(XcmsFailure); + } + + /* + * Now convert each XcmsColor structure to CIEXYZ form + */ + for (i = 0; i < nColors; i++, pColor++) { + + /* Make sure original format is CIELuv and is valid */ + if (!XcmsCIELuv_ValidSpec(pColor)) { + return(XcmsFailure); + } + + if (pColor->spec.CIELuv.L_star < 7.99953624) { + uvY_return.Y = pColor->spec.CIELuv.L_star / 903.29; + } else { + tmpVal = (pColor->spec.CIELuv.L_star + 16.0) / 116.0; + uvY_return.Y = tmpVal * tmpVal * tmpVal; /* tmpVal ** 3 */ + } + + + + if (pColor->spec.CIELuv.L_star == 0.0) { + uvY_return.u_prime = pLuv_WhitePt->spec.CIEuvY.u_prime; + uvY_return.v_prime = pLuv_WhitePt->spec.CIEuvY.v_prime; + } else { + tmpVal = 13.0 * (pColor->spec.CIELuv.L_star / 100.0); + uvY_return.u_prime = pColor->spec.CIELuv.u_star/tmpVal + + pLuv_WhitePt->spec.CIEuvY.u_prime; + uvY_return.v_prime = pColor->spec.CIELuv.v_star/tmpVal + + pLuv_WhitePt->spec.CIEuvY.v_prime; + } + /* Copy result to pColor */ + memcpy((char *)&pColor->spec, (char *)&uvY_return, sizeof(XcmsCIEuvY)); + + /* Identify that the format is now CIEuvY */ + pColor->format = XcmsCIEuvYFormat; + } + return(XcmsSuccess); +} + + +/* + * NAME + * XcmsCIEuvYToCIELuv - convert CIEuvY to CIELuv + * + * SYNOPSIS + */ +Status +XcmsCIEuvYToCIELuv(ccc, pLuv_WhitePt, pColors_in_out, nColors) + XcmsCCC ccc; + XcmsColor *pLuv_WhitePt; + XcmsColor *pColors_in_out; + unsigned int nColors; +/* + * DESCRIPTION + * Converts color specifications in an array of XcmsColor + * structures from CIEuvY format to CIELab format. + * + * RETURNS + * XcmsFailure if failed, + * XcmsSuccess if succeeded. + * + */ +{ + XcmsColor *pColor = pColors_in_out; + XcmsColor whitePt; + XcmsCIELuv Luv_return; + XcmsFloat tmpVal; + register int i; + + /* + * Check arguments + */ + if (pLuv_WhitePt == NULL || pColors_in_out == NULL) { + return(XcmsFailure); + } + + /* + * Make sure white point is in CIEuvY form + */ + if (pLuv_WhitePt->format != XcmsCIEuvYFormat) { + /* Make copy of the white point because we're going to modify it */ + memcpy((char *)&whitePt, (char *)pLuv_WhitePt, sizeof(XcmsColor)); + if (!_XcmsDIConvertColors(ccc, &whitePt, + (XcmsColor *)NULL, 1, XcmsCIEuvYFormat)) { + return(XcmsFailure); + } + pLuv_WhitePt = &whitePt; + } + /* Make sure it is a white point, i.e., Y == 1.0 */ + if (pLuv_WhitePt->spec.CIEuvY.Y != 1.0) { + return(XcmsFailure); + } + + /* + * Now convert each XcmsColor structure to CIEXYZ form + */ + for (i = 0; i < nColors; i++, pColor++) { + + if (!_XcmsCIEuvY_ValidSpec(pColor)) { + return(XcmsFailure); + } + + /* Now convert the uvY to Luv */ + Luv_return.L_star = + (pColor->spec.CIEuvY.Y < 0.008856) + ? + (pColor->spec.CIEuvY.Y * 903.29) + : + ((XcmsFloat)(XCMS_CUBEROOT(pColor->spec.CIEuvY.Y) * 116.0) - 16.0); + tmpVal = 13.0 * (Luv_return.L_star / 100.0); + Luv_return.u_star = tmpVal * + (pColor->spec.CIEuvY.u_prime - pLuv_WhitePt->spec.CIEuvY.u_prime); + Luv_return.v_star = tmpVal * + (pColor->spec.CIEuvY.v_prime - pLuv_WhitePt->spec.CIEuvY.v_prime); + + /* Copy result to pColor */ + memcpy((char *)&pColor->spec, (char *)&Luv_return, sizeof(XcmsCIELuv)); + + /* Identify that the format is now CIEuvY */ + pColor->format = XcmsCIELuvFormat; + } + return(XcmsSuccess); +} diff --git a/src/xcms/LuvGcC.c b/src/xcms/LuvGcC.c new file mode 100644 index 00000000..fa3b3f11 --- /dev/null +++ b/src/xcms/LuvGcC.c @@ -0,0 +1,124 @@ +/* $Xorg: LuvGcC.c,v 1.3 2000/08/17 19:44:41 cpqbld Exp $ */ + +/* + * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. + * All Rights Reserved + * + * This file is a component of an X Window System-specific implementation + * of XCMS based on the TekColor Color Management System. Permission is + * hereby granted to use, copy, modify, sell, and otherwise distribute this + * software and its documentation for any purpose and without fee, provided + * that this copyright, permission, and disclaimer notice is reproduced in + * all copies of this software and in supporting documentation. TekColor + * is a trademark of Tektronix, Inc. + * + * Tektronix makes no representation about the suitability of this software + * for any purpose. It is provided "as is" and with all faults. + * + * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, + * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX 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 THE PERFORMANCE OF THIS SOFTWARE. + * + * NAME + * CIELuvGcC.c + * + * DESCRIPTION + * Source for XcmsCIELuvClipuv() gamut compression routine. + * + */ + +#include "Xlibint.h" +#include "Xcmsint.h" + + +/************************************************************************ + * * + * PUBLIC ROUTINES * + * * + ************************************************************************/ + +/* + * NAME + * XcmsCIELuvClipuv - Reduce the chroma for a hue and L* + * + * SYNOPSIS + */ +/* ARGSUSED */ +Status +XcmsCIELuvClipuv (ccc, pColors_in_out, nColors, i, pCompressed) + XcmsCCC ccc; + XcmsColor *pColors_in_out; + unsigned int nColors; + unsigned int i; + Bool *pCompressed; +/* + * DESCRIPTION + * Reduce the Chroma for a specific hue and chroma to + * to bring the given color into the gamut of the + * specified device. As required of gamut compression + * functions, this routine returns pColor_in_out + * in XcmsCIEXYZFormat on successful completion. + * + * Since this routine works with the L* within + * pColor_in_out intermediate results may be returned + * even though it may be invalid. + * + * RETURNS + * XcmsFailure - Failure + * XcmsSuccess - Succeeded + * + */ +{ + Status retval; + XcmsColor *pColor; + + /* + * Color specification passed as input can be assumed to: + * 1. Be in XcmsCIEXYZFormat + * 2. Already be white point adjusted for the Screen White Point. + * This means that the white point now associated with this + * color spec is the Screen White Point (even if the + * ccc->clientWhitePt differs). + */ + + pColor = pColors_in_out + i; + + if (ccc->visual->class < PseudoColor) { + /* + * GRAY ! + */ + _XcmsDIConvertColors(ccc, pColor, ScreenWhitePointOfCCC(ccc), + 1, XcmsCIELuvFormat); + _XcmsDIConvertColors(ccc, pColor, ScreenWhitePointOfCCC(ccc), + 1, XcmsCIEXYZFormat); + if (pCompressed) { + *(pCompressed + i) = True; + } + return(XcmsSuccess); + } else { + if (pColor->format != XcmsCIELuvFormat) { + if (_XcmsDIConvertColors(ccc, pColor, + &ccc->pPerScrnInfo->screenWhitePt, 1, XcmsCIELuvFormat) + == XcmsFailure) { + return(XcmsFailure); + } + } + if (XcmsCIELuvQueryMaxC(ccc, + degrees(XCMS_CIELUV_PMETRIC_HUE(pColor->spec.CIELuv.u_star, + pColor->spec.CIELuv.v_star)), + pColor->spec.CIELuv.L_star, + pColor) == XcmsFailure) { + return(XcmsFailure); + } + retval = _XcmsDIConvertColors(ccc, pColor, + &ccc->pPerScrnInfo->screenWhitePt, 1, XcmsCIEXYZFormat); + if (retval != XcmsFailure && pCompressed != NULL) { + *(pCompressed + i) = True; + } + return(retval); + } +} diff --git a/src/xcms/LuvGcL.c b/src/xcms/LuvGcL.c new file mode 100644 index 00000000..32d09bdb --- /dev/null +++ b/src/xcms/LuvGcL.c @@ -0,0 +1,176 @@ +/* $Xorg: LuvGcL.c,v 1.3 2000/08/17 19:44:41 cpqbld Exp $ */ + +/* + * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. + * All Rights Reserved + * + * This file is a component of an X Window System-specific implementation + * of XCMS based on the TekColor Color Management System. Permission is + * hereby granted to use, copy, modify, sell, and otherwise distribute this + * software and its documentation for any purpose and without fee, provided + * that this copyright, permission, and disclaimer notice is reproduced in + * all copies of this software and in supporting documentation. TekColor + * is a trademark of Tektronix, Inc. + * + * Tektronix makes no representation about the suitability of this software + * for any purpose. It is provided "as is" and with all faults. + * + * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, + * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX 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 THE PERFORMANCE OF THIS SOFTWARE. + * + * NAME + * CIELuvGcL.c + * + * DESCRIPTION + * Source for XcmsCIELuvClipL() gamut compression routine. + * + */ + +#include "Xlibint.h" +#include "Xcmsint.h" + +/* + * EXTERNS + */ +extern Status _XcmsCIELuvQueryMaxLCRGB(); + + +/************************************************************************ + * * + * PUBLIC ROUTINES * + * * + ************************************************************************/ + +/* + * NAME + * XcmsCIELuvClipL - Return the closest L* + * + * SYNOPSIS + */ +/* ARGSUSED */ +Status +XcmsCIELuvClipL (ccc, pColors_in_out, nColors, i, pCompressed) + XcmsCCC ccc; + XcmsColor *pColors_in_out; + unsigned int nColors; + unsigned int i; + Bool *pCompressed; +/* + * DESCRIPTION + * Return the closest L* for a specific hue and chroma. + * This routine takes any color as input and outputs + * a CIE XYZ color. + * + * Since this routine works with the L* within + * pColor_in_out intermediate results may be returned + * even though it may be invalid. + * + * RETURNS + * XcmsFailure - Failure + * XcmsSuccess - Succeeded + * + */ +{ + XcmsCCCRec myCCC; + XcmsColor *pColor; + XcmsColor Luv_max; + XcmsFloat hue, chroma, maxChroma; + Status retval; + + /* Use my own CCC */ + memcpy ((char *)&myCCC, (char *)ccc, sizeof(XcmsCCCRec)); + myCCC.clientWhitePt.format = XcmsUndefinedFormat;/* Inherit Screen WP */ + myCCC.gamutCompProc = (XcmsCompressionProc)NULL;/* no gamut compression */ + + /* + * Color specification passed as input can be assumed to: + * 1. Be in XcmsCIEXYZFormat + * 2. Already be white point adjusted for the Screen White Point. + * This means that the white point now associated with this + * color spec is the Screen White Point (even if the + * ccc->clientWhitePt differs). + */ + + pColor = pColors_in_out + i; + + if (ccc->visual->class < StaticColor) { + /* + * GRAY ! + */ + return(XcmsFailure); + } else { + /* Convert from CIEXYZ to CIE L*u*v* format */ + if (_XcmsDIConvertColors(&myCCC, pColor, + ScreenWhitePointOfCCC(&myCCC), 1, XcmsCIELuvFormat) + == XcmsFailure) { + return(XcmsFailure); + } + + hue = XCMS_CIELUV_PMETRIC_HUE(pColor->spec.CIELuv.u_star, + pColor->spec.CIELuv.v_star); + chroma = XCMS_CIELUV_PMETRIC_CHROMA(pColor->spec.CIELuv.u_star, + pColor->spec.CIELuv.v_star); + /* Step 1: compute the maximum L* and chroma for this hue. */ + /* This copy may be overkill but it preserves the pixel etc. */ + memcpy((char *)&Luv_max, (char *)pColor, sizeof(XcmsColor)); + if (_XcmsCIELuvQueryMaxLCRGB (&myCCC, hue, &Luv_max, + (XcmsRGBi *)NULL) == XcmsFailure) { + return (XcmsFailure); + } + maxChroma = XCMS_CIELUV_PMETRIC_CHROMA(Luv_max.spec.CIELuv.u_star, + Luv_max.spec.CIELuv.v_star); + + /* Now check and return the appropriate L* */ + if (chroma == maxChroma) { + /* When the chroma input is equal to the maximum chroma */ + /* merely return the L* for that chroma. */ + memcpy((char *)pColor, (char *)&Luv_max, sizeof(XcmsColor)); + retval = _XcmsDIConvertColors(&myCCC, pColor, + ScreenWhitePointOfCCC(&myCCC), 1, XcmsCIEXYZFormat); + } else if (chroma > maxChroma) { + /* When the chroma input is greater than the maximum chroma */ + /* merely return the L* and chroma for the given hue. */ + memcpy((char *)pColor, (char *)&Luv_max, sizeof(XcmsColor)); + return (XcmsFailure); + } else if (pColor->spec.CIELuv.L_star < Luv_max.spec.CIELuv.L_star) { + /* Find the minimum lightness for the given chroma. */ + if (pColor->format != XcmsCIELuvFormat) { + if (_XcmsDIConvertColors(ccc, pColor, + ScreenWhitePointOfCCC(ccc), 1, XcmsCIELuvFormat) + == XcmsFailure) { + return(XcmsFailure); + } + } + if (XcmsCIELuvQueryMinL(&myCCC, degrees(hue), chroma, pColor) + == XcmsFailure) { + return (XcmsFailure); + } + retval = _XcmsDIConvertColors(&myCCC, pColor, + ScreenWhitePointOfCCC(&myCCC), 1, XcmsCIEXYZFormat); + } else { + /* Find the maximum lightness for the given chroma. */ + if (pColor->format != XcmsCIELuvFormat) { + if (_XcmsDIConvertColors(ccc, pColor, + ScreenWhitePointOfCCC(ccc), 1, XcmsCIELuvFormat) + == XcmsFailure) { + return(XcmsFailure); + } + } + if (XcmsCIELuvQueryMaxL(&myCCC, degrees(hue), chroma, pColor) + == XcmsFailure) { + return (XcmsFailure); + } + retval = _XcmsDIConvertColors(&myCCC, pColor, + ScreenWhitePointOfCCC(&myCCC), 1, XcmsCIEXYZFormat); + } + if (retval != XcmsFailure && pCompressed != NULL) { + *(pCompressed + i) = True; + } + return(retval); + } +} diff --git a/src/xcms/LuvGcLC.c b/src/xcms/LuvGcLC.c new file mode 100644 index 00000000..376f5f40 --- /dev/null +++ b/src/xcms/LuvGcLC.c @@ -0,0 +1,225 @@ +/* $Xorg: LuvGcLC.c,v 1.3 2000/08/17 19:44:41 cpqbld Exp $ */ + +/* + * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. + * All Rights Reserved + * + * This file is a component of an X Window System-specific implementation + * of XCMS based on the TekColor Color Management System. Permission is + * hereby granted to use, copy, modify, sell, and otherwise distribute this + * software and its documentation for any purpose and without fee, provided + * that this copyright, permission, and disclaimer notice is reproduced in + * all copies of this software and in supporting documentation. TekColor + * is a trademark of Tektronix, Inc. + * + * Tektronix makes no representation about the suitability of this software + * for any purpose. It is provided "as is" and with all faults. + * + * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, + * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX 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 THE PERFORMANCE OF THIS SOFTWARE. + * + * NAME + * CIELuvGcLC.c + * + * DESCRIPTION + * Source for XcmsCIELuvClipLuv() gamut + * compression function. + */ + +#include "Xlibint.h" +#include "Xcmsint.h" +#include <math.h> + +/* + * INTERNALS + * Internal defines that need NOT be exported to any package or + * program using this package. + */ +#define MAXBISECTCOUNT 100 + +/* + * EXTERNS + */ +extern Status _XcmsCIELuvQueryMaxLCRGB(); + + +/************************************************************************ + * * + * PUBLIC ROUTINES * + * * + ************************************************************************/ + +/* + * NAME + * XcmsCIELuvClipLuv - Return the closest L* and chroma + * + * SYNOPSIS + */ +/* ARGSUSED */ +Status +XcmsCIELuvClipLuv (ccc, pColors_in_out, nColors, i, pCompressed) + XcmsCCC ccc; + XcmsColor *pColors_in_out; + unsigned int nColors; + unsigned int i; + Bool *pCompressed; +/* + * DESCRIPTION + * This routine will find the closest L* and chroma + * for a specific hue. The color input is converted to + * CIE L*u*v* format and returned as CIE XYZ format. + * + * Since this routine works with the L* within + * pColor_in_out intermediate results may be returned + * even though it may be invalid. + * + * RETURNS + * XcmsFailure - Failure + * XcmsSuccess - Succeeded + * + */ +{ + Status retval; + XcmsCCCRec myCCC; + XcmsColor *pColor; + XcmsColor Luv_max; + XcmsFloat hue, chroma, maxChroma; + XcmsFloat Chroma, bestChroma, Lstar, maxLstar, saveLstar; + XcmsFloat bestLstar, bestustar, bestvstar; + XcmsFloat nT, saveDist, tmpDist; + XcmsRGBi rgb_max; + int nCount, nMaxCount, nI, nILast; + + /* Use my own CCC */ + memcpy ((char *)&myCCC, (char *)ccc, sizeof(XcmsCCCRec)); + myCCC.clientWhitePt.format = XcmsUndefinedFormat;/* inherit screen white */ + myCCC.gamutCompProc = (XcmsCompressionProc)NULL;/* no gamut compression func */ + + /* + * Color specification passed as input can be assumed to: + * 1. Be in XcmsCIEXYZFormat + * 2. Already be white point adjusted for the Screen White Point. + * This means that the white point now associated with this + * color spec is the Screen White Point (even if the + * ccc->clientWhitePt differs). + */ + + pColor = pColors_in_out + i; + + if (ccc->visual->class < StaticColor) { + /* + * GRAY ! + */ + _XcmsDIConvertColors(ccc, pColor, ScreenWhitePointOfCCC(ccc), + 1, XcmsCIELuvFormat); + _XcmsDIConvertColors(ccc, pColor, ScreenWhitePointOfCCC(ccc), + 1, XcmsCIEXYZFormat); + if (pCompressed) { + *(pCompressed + i) = True; + } + return(XcmsSuccess); + } + + /* Convert from CIEXYZ to CIELuv format */ + if (_XcmsDIConvertColors(&myCCC, pColor, + ScreenWhitePointOfCCC(&myCCC), 1, XcmsCIELuvFormat) + == XcmsFailure) { + return(XcmsFailure); + } + + /* Step 1: compute the maximum L* and chroma for this hue. */ + /* This copy may be overkill but it preserves the pixel etc. */ + saveLstar = pColor->spec.CIELuv.L_star; + hue = XCMS_CIELUV_PMETRIC_HUE(pColor->spec.CIELuv.u_star, + pColor->spec.CIELuv.v_star); + chroma = XCMS_CIELUV_PMETRIC_CHROMA(pColor->spec.CIELuv.u_star, + pColor->spec.CIELuv.v_star); + memcpy((char *)&Luv_max, (char *)pColor, sizeof(XcmsColor)); + if (_XcmsCIELuvQueryMaxLCRGB (&myCCC, hue, &Luv_max, &rgb_max) + == XcmsFailure) { + return (XcmsFailure); + } + maxLstar = Luv_max.spec.CIELuv.L_star; + + /* Now check and return the appropriate L* */ + if (saveLstar == maxLstar) { + /* When the L* input is equal to the maximum L* */ + /* merely return the maximum Luv point. */ + memcpy((char *)pColor, (char *)&Luv_max, sizeof(XcmsColor)); + retval = _XcmsDIConvertColors(&myCCC, pColor, + ScreenWhitePointOfCCC(&myCCC), 1, XcmsCIEXYZFormat); + } else { + /* return the closest point on the hue leaf. */ + /* must do a bisection here to compute the delta e. */ + maxChroma = XCMS_CIELUV_PMETRIC_CHROMA(Luv_max.spec.CIELuv.u_star, + Luv_max.spec.CIELuv.v_star); + nMaxCount = MAXBISECTCOUNT; + nI = nMaxCount / 2; + bestLstar = Lstar = pColor->spec.CIELuv.L_star; + bestustar = pColor->spec.CIELuv.u_star; + bestvstar = pColor->spec.CIELuv.v_star; + bestChroma = Chroma = chroma; + saveDist = XCMS_SQRT(((Chroma - maxChroma) * (Chroma - maxChroma)) + + ((Lstar - maxLstar) * (Lstar - maxLstar))); + for (nCount = 0; nCount < nMaxCount; nCount++) { + nT = (XcmsFloat) nI / (XcmsFloat) nMaxCount; + if (saveLstar > maxLstar) { + pColor->spec.RGBi.red = rgb_max.red * (1.0 - nT) + nT; + pColor->spec.RGBi.green = rgb_max.green * (1.0 - nT) + nT; + pColor->spec.RGBi.blue = rgb_max.blue * (1.0 - nT) + nT; + } else { + pColor->spec.RGBi.red = rgb_max.red - (rgb_max.red * nT); + pColor->spec.RGBi.green = rgb_max.green - (rgb_max.green * nT); + pColor->spec.RGBi.blue = rgb_max.blue - (rgb_max.blue * nT); + } + pColor->format = XcmsRGBiFormat; + + /* Convert from RGBi to CIE Luv */ + if (_XcmsConvertColorsWithWhitePt(&myCCC, pColor, + ScreenWhitePointOfCCC(&myCCC), 1, XcmsCIELuvFormat, + (Bool *) NULL) == XcmsFailure) { + return (XcmsFailure); + } + chroma = XCMS_CIELUV_PMETRIC_CHROMA(pColor->spec.CIELuv.u_star, + pColor->spec.CIELuv.v_star); + tmpDist = XCMS_SQRT(((Chroma - chroma) * (Chroma - chroma)) + + ((Lstar - pColor->spec.CIELuv.L_star) * + (Lstar - pColor->spec.CIELuv.L_star))); + nILast = nI; + if (tmpDist > saveDist) { + nI /= 2; + } else { + nI = (nMaxCount + nI) / 2; + saveDist = tmpDist; + bestLstar = pColor->spec.CIELuv.L_star; + bestustar = pColor->spec.CIELuv.u_star; + bestvstar = pColor->spec.CIELuv.v_star; + bestChroma = chroma; + } + if (nI == nILast || nI == 0) { + break; + } + } + if (bestChroma >= maxChroma) { + pColor->spec.CIELuv.L_star = maxLstar; + pColor->spec.CIELuv.u_star = Luv_max.spec.CIELuv.u_star; + pColor->spec.CIELuv.v_star = Luv_max.spec.CIELuv.v_star; + } else { + pColor->spec.CIELuv.L_star = bestLstar; + pColor->spec.CIELuv.u_star = bestustar; + pColor->spec.CIELuv.v_star = bestvstar; + } + retval = _XcmsDIConvertColors(&myCCC, pColor, + ScreenWhitePointOfCCC(&myCCC), 1, XcmsCIEXYZFormat); + + if (retval != XcmsFailure && pCompressed != NULL) { + *(pCompressed + i) = True; + } + } + return(retval); +} diff --git a/src/xcms/LuvMnL.c b/src/xcms/LuvMnL.c new file mode 100644 index 00000000..c687037d --- /dev/null +++ b/src/xcms/LuvMnL.c @@ -0,0 +1,218 @@ +/* $Xorg: LuvMnL.c,v 1.3 2000/08/17 19:44:41 cpqbld Exp $ */ + +/* + * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. + * All Rights Reserved + * + * This file is a component of an X Window System-specific implementation + * of XCMS based on the TekColor Color Management System. Permission is + * hereby granted to use, copy, modify, sell, and otherwise distribute this + * software and its documentation for any purpose and without fee, provided + * that this copyright, permission, and disclaimer notice is reproduced in + * all copies of this software and in supporting documentation. TekColor + * is a trademark of Tektronix, Inc. + * + * Tektronix makes no representation about the suitability of this software + * for any purpose. It is provided "as is" and with all faults. + * + * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, + * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX 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 THE PERFORMANCE OF THIS SOFTWARE. + * + * NAME + * CIELuvMnL.c + * + * DESCRIPTION + * Source for the XcmsCIELuvQueryMinL() gamut boundary + * querying routine. + * + */ + +#include "Xlibint.h" +#include "Xcmsint.h" +#include <math.h> + +/* + * DEFINES + */ +#define MAXBISECTCOUNT 100 +#define EPS (XcmsFloat)0.001 +#define START_L_STAR (XcmsFloat)40.0 + +/* + * EXTERNS + */ +extern Status _XcmsCIELuvQueryMaxLCRGB(); + + +/************************************************************************ + * * + * PUBLIC ROUTINES * + * * + ************************************************************************/ + +/* + * NAME + * XcmsCIELuvQueryMinL - Compute max Lstar for a hue and chroma + * + * SYNOPSIS + */ +Status +XcmsCIELuvQueryMinL(ccc, hue_angle, chroma, pColor_return) + XcmsCCC ccc; + XcmsFloat hue_angle; /* hue angle in degrees */ + XcmsFloat chroma; + XcmsColor *pColor_return; +/* + * DESCRIPTION + * Return the maximum Lstar for a specified hue_angle and chroma. + * + * ASSUMPTIONS + * This routine assumes that the white point associated with + * the color specification is the Screen White Point. The + * Screen White Point will also be associated with the + * returned color specification. + * + * RETURNS + * XcmsFailure - Failure + * XcmsSuccess - Succeeded with no modifications + * + */ +{ + XcmsCCCRec myCCC; + XcmsColor max_lc, tmp, prev; + XcmsFloat max_chroma, tmp_chroma; + XcmsFloat hue, nT, nChroma, lastChroma, prevChroma; + XcmsFloat rFactor; + XcmsRGBi rgb_saved; + int nCount, nMaxCount; + + /* + * Check Arguments + */ + if (ccc == NULL || pColor_return == NULL) { + return(XcmsFailure); + } + + /* setup the CCC to use for the conversions. */ + memcpy ((char *) &myCCC, (char *) ccc, sizeof(XcmsCCCRec)); + myCCC.clientWhitePt.format = XcmsUndefinedFormat; + myCCC.gamutCompProc = (XcmsCompressionProc) NULL; + + while (hue_angle < 0.0) { + hue_angle += 360.0; + } + while (hue_angle >= 360.0) { + hue_angle -= 360.0; + } + + hue = radians(hue_angle); + tmp.spec.CIELuv.L_star = START_L_STAR; + tmp.spec.CIELuv.u_star = XCMS_CIEUSTAROFHUE(hue, chroma); + tmp.spec.CIELuv.v_star = XCMS_CIEVSTAROFHUE(hue, chroma); + tmp.pixel = pColor_return->pixel; + tmp.format = XcmsCIELuvFormat; + + /* Step 1: Obtain the maximum L_star and chroma for this hue. */ + if (_XcmsCIELuvQueryMaxLCRGB(&myCCC, hue, &max_lc, &rgb_saved) + == XcmsFailure) { + return(XcmsFailure); + } + + max_chroma = XCMS_CIELUV_PMETRIC_CHROMA(max_lc.spec.CIELuv.u_star, + max_lc.spec.CIELuv.v_star); + + if (max_chroma <= chroma) { + /* + * If the chroma is greater than the chroma for the + * maximum L/chroma point then the L_star is the + * the L_star for the maximum L_star/chroma point. + * This is an error but I return the best approximation I can. + * Thus the inconsistency. + */ + memcpy ((char *) pColor_return, (char *) &max_lc, sizeof (XcmsColor)); + return(XcmsSuccess); + } + + /* + * If the chroma is equal to the chroma for the + * maximum L_star/chroma point then the L_star is the + * the L_star for the maximum L* and chroma point. + */ + /* if (max_chroma == chroma) { + * memcpy ((char *) pColor_return, (char *) &max_lc, sizeof (XcmsColor)); + * return(XcmsSuccess); + * } + */ + + /* must do a bisection here to compute the maximum L* */ + /* save the structure input so that any elements that */ + /* are not touched are recopied later in the routine. */ + nChroma = chroma; + tmp_chroma = max_chroma; + lastChroma = -1.0; + nMaxCount = MAXBISECTCOUNT; + rFactor = 1.0; + + for (nCount = 0; nCount < nMaxCount; nCount++) { + prevChroma = lastChroma; + lastChroma = tmp_chroma; + nT = (nChroma - max_chroma) / max_chroma * rFactor; + memcpy ((char *)&prev, (char *)&tmp, sizeof(XcmsColor)); + tmp.spec.RGBi.red = rgb_saved.red + (rgb_saved.red * nT); + tmp.spec.RGBi.green = rgb_saved.green + (rgb_saved.green * nT); + tmp.spec.RGBi.blue = rgb_saved.blue + (rgb_saved.blue * nT); + tmp.format = XcmsRGBiFormat; + + /* convert from RGB to CIELuv */ + if (_XcmsConvertColorsWithWhitePt(&myCCC, &tmp, + ScreenWhitePointOfCCC(&myCCC), 1, XcmsCIELuvFormat, + (Bool *) NULL) == XcmsFailure) { + return(XcmsFailure); + } + + /* Now check the return against what is expected */ + tmp_chroma = XCMS_CIELUV_PMETRIC_CHROMA(tmp.spec.CIELuv.u_star, + tmp.spec.CIELuv.v_star); + if (tmp_chroma <= chroma + EPS && tmp_chroma >= chroma - EPS) { + /* Found It! */ + memcpy ((char *) pColor_return, (char *) &tmp, sizeof (XcmsColor)); + return(XcmsSuccess); + } + nChroma += chroma - tmp_chroma; + if (nChroma > max_chroma) { + nChroma = max_chroma; + rFactor *= 0.5; /* selective relaxation employed */ + } else if (nChroma < 0.0) { + if (XCMS_FABS(lastChroma - chroma) < + XCMS_FABS(tmp_chroma - chroma)) { + memcpy ((char *)pColor_return, (char *)&prev, + sizeof(XcmsColor)); + } else { + memcpy ((char *)pColor_return, (char *)&tmp, + sizeof(XcmsColor)); + } + return(XcmsSuccess); + } else if (tmp_chroma <= prevChroma + EPS && + tmp_chroma >= prevChroma - EPS) { + rFactor *= 0.5; /* selective relaxation employed */ + } + } + + if (nCount >= nMaxCount) { + if (XCMS_FABS(lastChroma - chroma) < + XCMS_FABS(tmp_chroma - chroma)) { + memcpy ((char *)pColor_return, (char *)&prev, + sizeof(XcmsColor)); + } else { + memcpy ((char *)pColor_return, (char *)&tmp, + sizeof(XcmsColor)); + } + } + memcpy ((char *) pColor_return, (char *) &tmp, sizeof (XcmsColor)); + return(XcmsSuccess); +} diff --git a/src/xcms/LuvMxC.c b/src/xcms/LuvMxC.c new file mode 100644 index 00000000..100a3b9e --- /dev/null +++ b/src/xcms/LuvMxC.c @@ -0,0 +1,205 @@ +/* $Xorg: LuvMxC.c,v 1.3 2000/08/17 19:44:41 cpqbld Exp $ */ + +/* + * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. + * All Rights Reserved + * + * This file is a component of an X Window System-specific implementation + * of XCMS based on the TekColor Color Management System. Permission is + * hereby granted to use, copy, modify, sell, and otherwise distribute this + * software and its documentation for any purpose and without fee, provided + * that this copyright, permission, and disclaimer notice is reproduced in + * all copies of this software and in supporting documentation. TekColor + * is a trademark of Tektronix, Inc. + * + * Tektronix makes no representation about the suitability of this software + * for any purpose. It is provided "as is" and with all faults. + * + * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, + * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX 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 THE PERFORMANCE OF THIS SOFTWARE. + * + * + * + * NAME + * CIELuvMxC.c + * + * DESCRIPTION + * Source for the XcmsCIELuvQueryMaxC() gamut boundary + * querying routine. + * + */ + +#include "Xlibint.h" +#include "Xcmsint.h" +#include <math.h> + +/* + * DEFINES + */ +#define MAXBISECTCOUNT 100 +#define EPS (XcmsFloat)0.001 +#define START_CHROMA (XcmsFloat)2.2 +#define TOPL (XcmsFloat)100.0 +/* + * EXTERNS + */ +extern Status _XcmsCIELuvQueryMaxLCRGB(); + + +/************************************************************************ + * * + * PUBLIC ROUTINES * + * * + ************************************************************************/ + +/* + * NAME + * XcmsCIELuvQueryMaxC - max chroma for a hue_angle and L_star + * + * SYNOPSIS + */ +Status +XcmsCIELuvQueryMaxC(ccc, hue_angle, L_star, pColor_return) + XcmsCCC ccc; + XcmsFloat hue_angle; /* hue angle in degrees */ + XcmsFloat L_star; + XcmsColor *pColor_return; +/* + * DESCRIPTION + * Return the maximum chroma for a specific hue_angle and L_star. + * The returned format is in XcmsCIELuvFormat. + * + * + * ASSUMPTIONS + * This routine assumes that the white point associated with + * the color specification is the Screen White Point. The + * Screen White Point will also be associated with the + * returned color specification. + * + * RETURNS + * XcmsFailure - Failure + * XcmsSuccess - Succeeded + * + */ +{ + XcmsCCCRec myCCC; + XcmsColor tmp; + XcmsColor max_lc; + XcmsFloat n_L_star, last_L_star, prev_L_star; + XcmsFloat hue, lastuStar, lastvStar, /*lastChroma,*/ maxDist, nT, rFactor; + XcmsRGBi rgb_saved; + int nCount, nMaxCount; + + /* + * Check Arguments + */ + if (ccc == NULL || pColor_return == NULL) { + return(XcmsFailure); + } + + /* Use my own CCC and inherit screen white Pt */ + memcpy ((char *)&myCCC, (char *)ccc, sizeof(XcmsCCCRec)); + myCCC.clientWhitePt.format = XcmsUndefinedFormat; + myCCC.gamutCompProc = (XcmsCompressionProc)NULL;/* no gamut comp func */ + + while (hue_angle < 0.0) { + hue_angle += 360.0; + } + while (hue_angle >= 360.0) { + hue_angle -= 360.0; + } + + hue = radians(hue_angle); + tmp.spec.CIELuv.L_star = L_star; + tmp.spec.CIELuv.u_star = XCMS_CIEUSTAROFHUE(hue, START_CHROMA); + tmp.spec.CIELuv.v_star = XCMS_CIEVSTAROFHUE(hue, START_CHROMA); + tmp.pixel = pColor_return->pixel; + tmp.format = XcmsCIELuvFormat; + + /* Step 1: compute the maximum L_star and chroma for this hue. */ + memcpy((char *)&max_lc, (char *)&tmp, sizeof(XcmsColor)); + if (_XcmsCIELuvQueryMaxLCRGB(&myCCC, hue, &max_lc, &rgb_saved) + == XcmsFailure) { + return(XcmsFailure); + } + + /* + * Step 2: Do a bisection here to compute the maximum chroma + * Note the differences between when the point to be found + * is above the maximum LC point and when it is below. + */ + if (L_star <= max_lc.spec.CIELuv.L_star) { + maxDist = max_lc.spec.CIELuv.L_star; + } else { + maxDist = TOPL - max_lc.spec.CIELuv.L_star; + } + + n_L_star = L_star; + last_L_star = -1.0; + nMaxCount = MAXBISECTCOUNT; + rFactor = 1.0; + + for (nCount = 0; nCount < nMaxCount; nCount++) { + prev_L_star = last_L_star; + last_L_star = tmp.spec.CIELuv.L_star; +/* lastChroma = XCMS_CIELUV_PMETRIC_CHROMA(tmp.spec.CIELuv.u_star, */ +/* tmp.spec.CIELuv.v_star); */ + lastuStar = tmp.spec.CIELuv.u_star; + lastvStar = tmp.spec.CIELuv.v_star; + nT = (n_L_star - max_lc.spec.CIELuv.L_star) / maxDist * rFactor; + /* printf("(n_L_star, nT) = %lf %lf ", n_L_star, nT); */ + if (nT > 0) { + tmp.spec.RGBi.red = rgb_saved.red * (1.0 - nT) + nT; + tmp.spec.RGBi.green = rgb_saved.green * (1.0 - nT) + nT; + tmp.spec.RGBi.blue = rgb_saved.blue * (1.0 - nT) + nT; + } else { + tmp.spec.RGBi.red = rgb_saved.red + (rgb_saved.red * nT); + tmp.spec.RGBi.green = rgb_saved.green + (rgb_saved.green * nT); + tmp.spec.RGBi.blue = rgb_saved.blue + (rgb_saved.blue * nT); + } + tmp.format = XcmsRGBiFormat; + + /* convert from RGB to CIELuv */ + if (_XcmsConvertColorsWithWhitePt(&myCCC, &tmp, + ScreenWhitePointOfCCC(&myCCC), 1, XcmsCIELuvFormat, + (Bool *) NULL) == XcmsFailure) { + return(XcmsFailure); + } + + /* + * Now check if we've reached the target L_star + */ + /* printf("result Lstar = %lf\n", tmp.spec.CIELuv.L_star); */ + if (tmp.spec.CIELuv.L_star <= L_star + EPS && + tmp.spec.CIELuv.L_star >= L_star - EPS) { + memcpy((char *)pColor_return, (char *)&tmp, sizeof(XcmsColor)); + return(XcmsSuccess); + } + if (nT > 0) { + n_L_star += ((TOPL - n_L_star) * + (L_star - tmp.spec.CIELuv.L_star)) / (TOPL - L_star); + } else { + n_L_star *= L_star / tmp.spec.CIELuv.L_star; + } + if (tmp.spec.CIELuv.L_star <= prev_L_star + EPS && + tmp.spec.CIELuv.L_star >= prev_L_star - EPS) { + rFactor *= 0.5; /* selective relaxation employed */ + /* printf("rFactor = %lf\n", rFactor); */ + } + } + if (XCMS_FABS(last_L_star - L_star) < + XCMS_FABS(tmp.spec.CIELuv.L_star - L_star)) { + tmp.spec.CIELuv.u_star = lastuStar; + tmp.spec.CIELuv.v_star = lastvStar; +/* tmp.spec.CIELuv.u_star = XCMS_CIEUSTAROFHUE(hue, lastChroma); */ +/* tmp.spec.CIELuv.v_star = XCMS_CIEVSTAROFHUE(hue, lastChroma); */ + } + tmp.spec.CIELuv.L_star = L_star; + memcpy((char *)pColor_return, (char *)&tmp, sizeof(XcmsColor)); + return(XcmsSuccess); +} diff --git a/src/xcms/LuvMxL.c b/src/xcms/LuvMxL.c new file mode 100644 index 00000000..7925b010 --- /dev/null +++ b/src/xcms/LuvMxL.c @@ -0,0 +1,218 @@ +/* $Xorg: LuvMxL.c,v 1.3 2000/08/17 19:44:45 cpqbld Exp $ */ + +/* + * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. + * All Rights Reserved + * + * This file is a component of an X Window System-specific implementation + * of XCMS based on the TekColor Color Management System. Permission is + * hereby granted to use, copy, modify, sell, and otherwise distribute this + * software and its documentation for any purpose and without fee, provided + * that this copyright, permission, and disclaimer notice is reproduced in + * all copies of this software and in supporting documentation. TekColor + * is a trademark of Tektronix, Inc. + * + * Tektronix makes no representation about the suitability of this software + * for any purpose. It is provided "as is" and with all faults. + * + * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, + * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX 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 THE PERFORMANCE OF THIS SOFTWARE. + * + * NAME + * CIELuvMxL.c + * + * DESCRIPTION + * Source for the XcmsCIELuvQueryMaxL() gamut boundary + * querying routine. + * + */ + +#include "Xlibint.h" +#include "Xcmsint.h" +#include <math.h> + +/* + * DEFINES + */ +#define MAXBISECTCOUNT 100 +#define EPS (XcmsFloat)0.001 +#define START_L_STAR (XcmsFloat)40.0 + +/* + * EXTERNS + */ +extern Status _XcmsCIELuvQueryMaxLCRGB(); + + +/************************************************************************ + * * + * PUBLIC ROUTINES * + * * + ************************************************************************/ + +/* + * NAME + * XcmsCIELuvQueryMaxL - Compute max Lstar for a hue and chroma + * + * SYNOPSIS + */ +Status +XcmsCIELuvQueryMaxL(ccc, hue_angle, chroma, pColor_return) + XcmsCCC ccc; + XcmsFloat hue_angle; /* hue angle in degrees */ + XcmsFloat chroma; + XcmsColor *pColor_return; +/* + * DESCRIPTION + * Return the maximum Lstar for a specified hue_angle and chroma. + * + * ASSUMPTIONS + * This routine assumes that the white point associated with + * the color specification is the Screen White Point. The + * Screen White Point will also be associated with the + * returned color specification. + * + * RETURNS + * XcmsFailure - Failure + * XcmsSuccess - Succeeded with no modifications + * + */ +{ + XcmsCCCRec myCCC; + XcmsColor max_lc, tmp, prev; + XcmsFloat max_chroma, tmp_chroma; + XcmsFloat hue, nT, nChroma, lastChroma, prevChroma; + XcmsFloat rFactor; + XcmsRGBi rgb_saved; + int nCount, nMaxCount; + + /* + * Check Arguments + */ + if (ccc == NULL || pColor_return == NULL) { + return(XcmsFailure); + } + + /* setup the CCC to use for the conversions. */ + memcpy ((char *) &myCCC, (char *) ccc, sizeof(XcmsCCCRec)); + myCCC.clientWhitePt.format = XcmsUndefinedFormat; + myCCC.gamutCompProc = (XcmsCompressionProc) NULL; + + while (hue_angle < 0.0) { + hue_angle += 360.0; + } + while (hue_angle >= 360.0) { + hue_angle -= 360.0; + } + + hue = radians(hue_angle); + tmp.spec.CIELuv.L_star = START_L_STAR; + tmp.spec.CIELuv.u_star = XCMS_CIEUSTAROFHUE(hue, chroma); + tmp.spec.CIELuv.v_star = XCMS_CIEVSTAROFHUE(hue, chroma); + tmp.pixel = pColor_return->pixel; + tmp.format = XcmsCIELuvFormat; + + /* Step 1: Obtain the maximum L_star and chroma for this hue. */ + if (_XcmsCIELuvQueryMaxLCRGB(&myCCC, hue, &max_lc, &rgb_saved) + == XcmsFailure) { + return(XcmsFailure); + } + + max_chroma = XCMS_CIELUV_PMETRIC_CHROMA(max_lc.spec.CIELuv.u_star, + max_lc.spec.CIELuv.v_star); + + if (max_chroma <= chroma) { + /* + * If the chroma is greater than the chroma for the + * maximum L/chroma point then the L_star is the + * the L_star for the maximum L_star/chroma point. + * This is an error but I return the best approximation I can. + * Thus the inconsistency. + */ + memcpy ((char *) pColor_return, (char *) &max_lc, sizeof (XcmsColor)); + return(XcmsSuccess); + } + + /* + * If the chroma is equal to the chroma for the + * maximum L_star/chroma point then the L_star is the + * the L_star for the maximum L* and chroma point. + */ + /* if (max_chroma == chroma) { + * memcpy ((char *) pColor_return, (char *) &max_lc, sizeof (XcmsColor)); + * return(XcmsSuccess); + * } + */ + + /* must do a bisection here to compute the maximum L* */ + /* save the structure input so that any elements that */ + /* are not touched are recopied later in the routine. */ + nChroma = chroma; + tmp_chroma = max_chroma; + lastChroma = -1.0; + nMaxCount = MAXBISECTCOUNT; + rFactor = 1.0; + + for (nCount = 0; nCount < nMaxCount; nCount++) { + prevChroma = lastChroma; + lastChroma = tmp_chroma; + nT = (1.0 - (nChroma / max_chroma)) * rFactor; + memcpy ((char *)&prev, (char *)&tmp, sizeof(XcmsColor)); + tmp.spec.RGBi.red = rgb_saved.red * (1.0 - nT) + nT; + tmp.spec.RGBi.green = rgb_saved.green * (1.0 - nT) + nT; + tmp.spec.RGBi.blue = rgb_saved.blue * (1.0 - nT) + nT; + tmp.format = XcmsRGBiFormat; + + /* convert from RGB to CIELuv */ + if (_XcmsConvertColorsWithWhitePt(&myCCC, &tmp, + ScreenWhitePointOfCCC(&myCCC), 1, XcmsCIELuvFormat, + (Bool *) NULL) == XcmsFailure) { + return(XcmsFailure); + } + + /* Now check the return against what is expected */ + tmp_chroma = XCMS_CIELUV_PMETRIC_CHROMA(tmp.spec.CIELuv.u_star, + tmp.spec.CIELuv.v_star); + if (tmp_chroma <= chroma + EPS && tmp_chroma >= chroma - EPS) { + /* Found It! */ + memcpy ((char *) pColor_return, (char *) &tmp, sizeof (XcmsColor)); + return(XcmsSuccess); + } + nChroma += chroma - tmp_chroma; + if (nChroma > max_chroma) { + nChroma = max_chroma; + rFactor *= 0.5; /* selective relaxation employed */ + } else if (nChroma < 0.0) { + if (XCMS_FABS(lastChroma - chroma) < + XCMS_FABS(tmp_chroma - chroma)) { + memcpy ((char *)pColor_return, (char *)&prev, + sizeof(XcmsColor)); + } else { + memcpy ((char *)pColor_return, (char *)&tmp, + sizeof(XcmsColor)); + } + return(XcmsSuccess); + } else if (tmp_chroma <= prevChroma + EPS && + tmp_chroma >= prevChroma - EPS) { + rFactor *= 0.5; /* selective relaxation employed */ + } + } + + if (nCount >= nMaxCount) { + if (XCMS_FABS(lastChroma - chroma) < + XCMS_FABS(tmp_chroma - chroma)) { + memcpy ((char *)pColor_return, (char *)&prev, + sizeof(XcmsColor)); + } else { + memcpy ((char *)pColor_return, (char *)&tmp, + sizeof(XcmsColor)); + } + } + memcpy ((char *) pColor_return, (char *) &tmp, sizeof (XcmsColor)); + return(XcmsSuccess); +} diff --git a/src/xcms/LuvMxLC.c b/src/xcms/LuvMxLC.c new file mode 100644 index 00000000..337bbbf2 --- /dev/null +++ b/src/xcms/LuvMxLC.c @@ -0,0 +1,226 @@ +/* $Xorg: LuvMxLC.c,v 1.3 2000/08/17 19:44:45 cpqbld Exp $ */ + +/* + * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. + * All Rights Reserved + * + * This file is a component of an X Window System-specific implementation + * of XCMS based on the TekColor Color Management System. Permission is + * hereby granted to use, copy, modify, sell, and otherwise distribute this + * software and its documentation for any purpose and without fee, provided + * that this copyright, permission, and disclaimer notice is reproduced in + * all copies of this software and in supporting documentation. TekColor + * is a trademark of Tektronix, Inc. + * + * Tektronix makes no representation about the suitability of this software + * for any purpose. It is provided "as is" and with all faults. + * + * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, + * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX 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 THE PERFORMANCE OF THIS SOFTWARE. + * + * + * + * NAME + * CIELuvMxVC.c + * + * DESCRIPTION + * Source for the XcmsCIELuvQueryMaxLC() gamut boundary + * querying routine. + * + * DOCUMENTATION + * "TekColor Color Management System, System Implementor's Manual" + * and + * Fred W. Billmeyer & Max Saltzman, "Principles of Color + * Technology", John Wily & Sons, Inc, 1981. + */ + +#include "Xlibint.h" +#include "Xcmsint.h" + +/* + * DEFINES + */ +#define MIN(x,y) ((x) > (y) ? (y) : (x)) +#define MIN3(x,y,z) ((x) > (MIN((y), (z))) ? (MIN((y), (z))) : (x)) +#define MAX(x,y) ((x) > (y) ? (x) : (y)) +#define MAX3(x,y,z) ((x) > (MAX((y), (z))) ? (x) : (MAX((y), (z)))) +#define START_LSTAR (XcmsFloat)40.0 +#define START_CHROMA (XcmsFloat)2.2 + +/* + * EXTERNS + */ +extern Status _XcmsConvertColorsWithWhitePt(); + +/* + * FORWARD DECLARATIONS + */ +Status _XcmsCIELuvQueryMaxLCRGB(); + + +/************************************************************************ + * * + * API PRIVATE ROUTINES * + * * + ************************************************************************/ + +/* + * NAME + * _XcmsCIELuvQueryMaxLCRGB - Compute maximum L* and chroma. + * + * SYNOPSIS + */ +Status +_XcmsCIELuvQueryMaxLCRGB(ccc, hue, pColor_return, pRGB_return) + XcmsCCC ccc; + XcmsFloat hue; /* hue in radians */ + XcmsColor *pColor_return; + XcmsRGBi *pRGB_return; + +/* + * DESCRIPTION + * Return the maximum psychometric chroma for a specified + * hue angle(radians), and the corresponding L*. This is computed + * by a binary search of all possible chromas. An assumption + * is made that there are no local maxima. Use the unrounded + * Max psychometric chroma because the difference check can be + * small. + * + * NOTE: No local CCC is used because this is a private + * routine and all routines that call it are expected + * to behave properly, i.e. send a local CCC with + * no white adjust function and no gamut compression + * function. + * + * This routine only accepts hue as input and outputs + * Luv and RGBi. + * + * RETURNS + * XcmsFailure - Failure + * XcmsSuccess - Succeeded + * + */ +{ + XcmsFloat nSmall, nLarge; + XcmsColor tmp; + + tmp.format = XcmsCIELuvFormat; + /* Use some unreachable color on the given hue angle */ + tmp.spec.CIELuv.L_star = START_LSTAR; + tmp.spec.CIELuv.u_star = XCMS_CIEUSTAROFHUE(hue, START_CHROMA); + tmp.spec.CIELuv.v_star = XCMS_CIEVSTAROFHUE(hue, START_CHROMA); + /* + * Convert from Luv to RGB + * + * Note that the CIEXYZ to RGBi conversion routine must stuff the + * out of bounds RGBi values in tmp when the ccc->gamutCompProc + * is NULL. + */ + if ((_XcmsConvertColorsWithWhitePt(ccc, &tmp, ScreenWhitePointOfCCC(ccc), + (unsigned int)1, XcmsRGBiFormat, (Bool *) NULL) + == XcmsFailure) && tmp.format != XcmsRGBiFormat) { + return (XcmsFailure); + } + + /* Now pick the smallest RGB */ + nSmall = MIN3(tmp.spec.RGBi.red, + tmp.spec.RGBi.green, + tmp.spec.RGBi.blue); + /* Make the smallest RGB equal to zero */ + tmp.spec.RGBi.red -= nSmall; + tmp.spec.RGBi.green -= nSmall; + tmp.spec.RGBi.blue -= nSmall; + + /* Now pick the largest RGB */ + nLarge = MAX3(tmp.spec.RGBi.red, + tmp.spec.RGBi.green, + tmp.spec.RGBi.blue); + /* Scale the RGB values based on the largest one */ + tmp.spec.RGBi.red /= nLarge; + tmp.spec.RGBi.green /= nLarge; + tmp.spec.RGBi.blue /= nLarge; + tmp.format = XcmsRGBiFormat; + + /* If the calling routine wants RGB value give them the ones used. */ + if (pRGB_return) { + pRGB_return->red = tmp.spec.RGBi.red; + pRGB_return->green = tmp.spec.RGBi.green; + pRGB_return->blue = tmp.spec.RGBi.blue; + } + + /* Convert from RGBi to Luv */ + if (_XcmsConvertColorsWithWhitePt(ccc, &tmp, + ScreenWhitePointOfCCC(ccc), 1, XcmsCIELuvFormat, (Bool *) NULL) + == XcmsFailure) { + return (XcmsFailure); + } + + memcpy((char *)pColor_return, (char *)&tmp, sizeof(XcmsColor)); + return (XcmsSuccess); +} + + +/************************************************************************ + * * + * PUBLIC ROUTINES * + * * + ************************************************************************/ + +/* + * NAME + * XcmsCIELuvQueryMaxLC - Compute maximum L* and chroma. + * + * SYNOPSIS + */ +Status +XcmsCIELuvQueryMaxLC (ccc, hue_angle, pColor_return) + XcmsCCC ccc; + XcmsFloat hue_angle; /* hue angle in degrees */ + XcmsColor *pColor_return; + +/* + * DESCRIPTION + * Return the point of maximum chroma for the specified + * hue angle. + * + * ASSUMPTIONS + * This routine assumes that the white point associated with + * the color specification is the Screen White Point. The + * Screen White Point will also be associated with the + * returned color specification. + * + * RETURNS + * XcmsFailure - Failure + * XcmsSuccess - Succeeded + * + */ +{ + XcmsCCCRec myCCC; + + /* + * Check Arguments + */ + if (ccc == NULL || pColor_return == NULL) { + return(XcmsFailure); + } + + /* Use my own CCC */ + memcpy ((char *)&myCCC, (char *)ccc, sizeof(XcmsCCCRec)); + myCCC.clientWhitePt.format = XcmsUndefinedFormat; + myCCC.gamutCompProc = (XcmsCompressionProc)NULL; + + while (hue_angle < 0.0) { + hue_angle += 360.0; + } + while (hue_angle >= 360.0) { + hue_angle -= 360.0; + } + + return(_XcmsCIELuvQueryMaxLCRGB (&myCCC, radians(hue_angle), pColor_return, + (XcmsRGBi *)NULL)); +} diff --git a/src/xcms/LuvWpAj.c b/src/xcms/LuvWpAj.c new file mode 100644 index 00000000..5083ccb7 --- /dev/null +++ b/src/xcms/LuvWpAj.c @@ -0,0 +1,100 @@ +/* $Xorg: LuvWpAj.c,v 1.3 2000/08/17 19:44:45 cpqbld Exp $ */ + +/* + * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. + * All Rights Reserved + * + * This file is a component of an X Window System-specific implementation + * of XCMS based on the TekColor Color Management System. Permission is + * hereby granted to use, copy, modify, sell, and otherwise distribute this + * software and its documentation for any purpose and without fee, provided + * that this copyright, permission, and disclaimer notice is reproduced in + * all copies of this software and in supporting documentation. TekColor + * is a trademark of Tektronix, Inc. + * + * Tektronix makes no representation about the suitability of this software + * for any purpose. It is provided "as is" and with all faults. + * + * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, + * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX 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 THE PERFORMANCE OF THIS SOFTWARE. + * + * + * NAME + * CIELuvWpAj.c + * + * DESCRIPTION + * This file contains routine(s) that support white point + * adjustment of color specifications in the CIE CIELuv.color + * space. + */ + +#include "Xlibint.h" +#include "Xcmsint.h" + +/* + * EXTERNS + */ + +extern Status _XcmsConvertColorsWithWhitePt(); + + + +/************************************************************************ + * * + * PUBLIC ROUTINES * + * * + ************************************************************************/ + +/* + * NAME + * XcmsCIELuvWhiteShiftColors + * + * SYNOPSIS + */ +Status +XcmsCIELuvWhiteShiftColors(ccc, pWhitePtFrom, pWhitePtTo, destSpecFmt, + pColors_in_out, nColors, pCompressed) + XcmsCCC ccc; + XcmsColor *pWhitePtFrom; + XcmsColor *pWhitePtTo; + XcmsColorFormat destSpecFmt; + XcmsColor *pColors_in_out; + unsigned int nColors; + Bool *pCompressed; +/* + * DESCRIPTION + * Adjusts color specifications in an array of XcmsColor + * structures for white point differences. + * + * RETURNS + * XcmsFailure if failed, + * XcmsSuccess if succeeded without gamut compression, + * XcmsSuccessWithCompression if succeeded with + * gamut compression. + */ +{ + if (pWhitePtFrom == NULL || pWhitePtTo == NULL || pColors_in_out == NULL) { + return(XcmsFailure); + } + + /* + * Convert to CIELuv using pWhitePtFrom + * We can ignore return value for compression because we are converting + * to XcmsCIELuvFormat which is device-independent, not device-dependent. + */ + if (_XcmsConvertColorsWithWhitePt(ccc, pColors_in_out, pWhitePtFrom, + nColors, XcmsCIELuvFormat, pCompressed) == XcmsFailure) { + return(XcmsFailure); + } + + /* + * Convert from CIELuv to destSpecFmt using pWhitePtTo + */ + return(_XcmsConvertColorsWithWhitePt(ccc, pColors_in_out, pWhitePtTo, + nColors, destSpecFmt, pCompressed)); +} diff --git a/src/xcms/OfCCC.c b/src/xcms/OfCCC.c new file mode 100644 index 00000000..20d3a9be --- /dev/null +++ b/src/xcms/OfCCC.c @@ -0,0 +1,160 @@ +/* $Xorg: OfCCC.c,v 1.3 2000/08/17 19:44:47 cpqbld Exp $ */ + +/* + * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. + * All Rights Reserved + * + * This file is a component of an X Window System-specific implementation + * of Xcms based on the TekColor Color Management System. Permission is + * hereby granted to use, copy, modify, sell, and otherwise distribute this + * software and its documentation for any purpose and without fee, provided + * that this copyright, permission, and disclaimer notice is reproduced in + * all copies of this software and in supporting documentation. TekColor + * is a trademark of Tektronix, Inc. + * + * Tektronix makes no representation about the suitability of this software + * for any purpose. It is provided "as is" and with all faults. + * + * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, + * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX 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 THE PERFORMANCE OF THIS SOFTWARE. + * + * + * NAME + * XcmsOfCCC.c - Color Conversion Context Querying Routines + * + * DESCRIPTION + * Routines to query components of a Color Conversion + * Context structure. + * + * + */ + +#include "Xlib.h" +#include "Xcms.h" + + + +/************************************************************************ + * * + * PUBLIC INTERFACES * + * * + ************************************************************************/ + +/* + * NAME + * XcmsDisplayOfCCC + * + * SYNOPSIS + */ + +Display * +XcmsDisplayOfCCC(ccc) + XcmsCCC ccc; +/* + * DESCRIPTION + * Queries the Display of the specified CCC. + * + * RETURNS + * Pointer to the Display. + * + */ +{ + return(ccc->dpy); +} + + +/* + * NAME + * XcmsVisualOfCCC + * + * SYNOPSIS + */ + +Visual * +XcmsVisualOfCCC(ccc) + XcmsCCC ccc; +/* + * DESCRIPTION + * Queries the Visual of the specified CCC. + * + * RETURNS + * Pointer to the Visual. + * + */ +{ + return(ccc->visual); +} + + +/* + * NAME + * XcmsScreenNumberOfCCC + * + * SYNOPSIS + */ + +int +XcmsScreenNumberOfCCC(ccc) + XcmsCCC ccc; +/* + * DESCRIPTION + * Queries the screen number of the specified CCC. + * + * RETURNS + * screen number. + * + */ +{ + return(ccc->screenNumber); +} + + +/* + * NAME + * XcmsScreenWhitePointOfCCC + * + * SYNOPSIS + */ + +XcmsColor * +XcmsScreenWhitePointOfCCC(ccc) + XcmsCCC ccc; +/* + * DESCRIPTION + * Queries the screen white point of the specified CCC. + * + * RETURNS + * Pointer to the XcmsColor containing the screen white point. + * + */ +{ + return(&ccc->pPerScrnInfo->screenWhitePt); +} + + +/* + * NAME + * XcmsClientWhitePointOfCCC + * + * SYNOPSIS + */ + +XcmsColor * +XcmsClientWhitePointOfCCC(ccc) + XcmsCCC ccc; +/* + * DESCRIPTION + * Queries the client white point of the specified CCC. + * + * RETURNS + * Pointer to the XcmsColor containing the client white point. + * + */ +{ + return(&ccc->clientWhitePt); +} diff --git a/src/xcms/PrOfId.c b/src/xcms/PrOfId.c new file mode 100644 index 00000000..7b301e41 --- /dev/null +++ b/src/xcms/PrOfId.c @@ -0,0 +1,107 @@ +/* $Xorg: PrOfId.c,v 1.3 2000/08/17 19:44:48 cpqbld Exp $ */ + +/* + * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. + * All Rights Reserved + * + * This file is a component of an X Window System-specific implementation + * of Xcms based on the TekColor Color Management System. Permission is + * hereby granted to use, copy, modify, sell, and otherwise distribute this + * software and its documentation for any purpose and without fee, provided + * that this copyright, permission, and disclaimer notice is reproduced in + * all copies of this software and in supporting documentation. TekColor + * is a trademark of Tektronix, Inc. + * + * Tektronix makes no representation about the suitability of this software + * for any purpose. It is provided "as is" and with all faults. + * + * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, + * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX 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 THE PERFORMANCE OF THIS SOFTWARE. + * + * + * NAME + * XcmsPrOfId.c + * + * DESCRIPTION + * Source for XcmsPrefixOfFormat() + * + * + */ + +#include "Xlibint.h" +#include "Xcmsint.h" + +/* + * EXTERNS + */ +extern XcmsColorSpace **_XcmsDIColorSpaces; +extern XcmsColorSpace **_XcmsDDColorSpaces; + + +/* + * NAME + * XcmsPrefixOfId + * + * SYNOPSIS + */ +char * +XcmsPrefixOfFormat(id) + XcmsColorFormat id; +/* + * DESCRIPTION + * Returns the color space prefix for the specified color + * space ID if the color space is found in the Color + * Conversion Context. + * + * RETURNS + * Returns a color space prefix. + * + * CAVEATS + * Space is allocated for the returned string, therefore, + * the application is responsible for freeing (using XFree) + * the space. + * + */ +{ + XcmsColorSpace **papColorSpaces; + char *prefix; + + /* + * First try Device-Independent color spaces + */ + papColorSpaces = _XcmsDIColorSpaces; + if (papColorSpaces != NULL) { + while (*papColorSpaces != NULL) { + if ((*papColorSpaces)->id == id) { + prefix = (char *)Xmalloc((strlen((*papColorSpaces)->prefix) + + 1) * sizeof(char)); + strcpy(prefix, (*papColorSpaces)->prefix); + return(prefix); + } + papColorSpaces++; + } + } + + /* + * Next try Device-Dependent color spaces + */ + papColorSpaces = _XcmsDDColorSpaces; + if (papColorSpaces != NULL) { + while (*papColorSpaces != NULL) { + if ((*papColorSpaces)->id == id) { + prefix = (char *)Xmalloc((strlen((*papColorSpaces)->prefix) + + 1) * sizeof(char)); + strcpy(prefix, (*papColorSpaces)->prefix); + return(prefix); + } + papColorSpaces++; + } + } + + return(NULL); +} diff --git a/src/xcms/QBlack.c b/src/xcms/QBlack.c new file mode 100644 index 00000000..c54dccb4 --- /dev/null +++ b/src/xcms/QBlack.c @@ -0,0 +1,82 @@ +/* $Xorg: QBlack.c,v 1.3 2000/08/17 19:44:49 cpqbld Exp $ */ + +/* + * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. + * All Rights Reserved + * + * This file is a component of an X Window System-specific implementation + * of Xcms based on the TekColor Color Management System. Permission is + * hereby granted to use, copy, modify, sell, and otherwise distribute this + * software and its documentation for any purpose and without fee, provided + * that this copyright, permission, and disclaimer notice is reproduced in + * all copies of this software and in supporting documentation. TekColor + * is a trademark of Tektronix, Inc. + * + * Tektronix makes no representation about the suitability of this software + * for any purpose. It is provided "as is" and with all faults. + * + * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, + * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX 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 THE PERFORMANCE OF THIS SOFTWARE. + * + * + * NAME + * XcmsQBlack.c - Query Black + * + * DESCRIPTION + * Routine to obtain a color specification for zero + * red, green, and blue intensities. + * + * + */ + +#include "Xlibint.h" +#include "Xcms.h" + + + +/************************************************************************ + * * + * PUBLIC INTERFACES * + * * + ************************************************************************/ + +/* + * NAME + * XcmsQueryBlack + * + * SYNOPSIS + */ + +Status +XcmsQueryBlack(ccc, target_format, pColor_ret) + XcmsCCC ccc; + XcmsColorFormat target_format; + XcmsColor *pColor_ret; +/* + * DESCRIPTION + * Returns the color specification in the target format for + * zero intensity red, green, and blue. + * + * RETURNS + * Returns XcmsSuccess, if failed; otherwise XcmsFailure + * + */ +{ + XcmsColor tmp; + + tmp.format = XcmsRGBiFormat; + tmp.pixel = 0; + tmp.spec.RGBi.red = 0.0; + tmp.spec.RGBi.green = 0.0; + tmp.spec.RGBi.blue = 0.0; + if (XcmsConvertColors(ccc, &tmp, 1, target_format, NULL) != XcmsSuccess) { + return(XcmsFailure); + } + memcpy((char *)pColor_ret, (char *)&tmp, sizeof(XcmsColor)); + return(XcmsSuccess); +} diff --git a/src/xcms/QBlue.c b/src/xcms/QBlue.c new file mode 100644 index 00000000..2bca3877 --- /dev/null +++ b/src/xcms/QBlue.c @@ -0,0 +1,82 @@ +/* $Xorg: QBlue.c,v 1.3 2000/08/17 19:44:49 cpqbld Exp $ */ + +/* + * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. + * All Rights Reserved + * + * This file is a component of an X Window System-specific implementation + * of Xcms based on the TekColor Color Management System. Permission is + * hereby granted to use, copy, modify, sell, and otherwise distribute this + * software and its documentation for any purpose and without fee, provided + * that this copyright, permission, and disclaimer notice is reproduced in + * all copies of this software and in supporting documentation. TekColor + * is a trademark of Tektronix, Inc. + * + * Tektronix makes no representation about the suitability of this software + * for any purpose. It is provided "as is" and with all faults. + * + * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, + * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX 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 THE PERFORMANCE OF THIS SOFTWARE. + * + * + * NAME + * XcmsQBlue.c - Query Blue + * + * DESCRIPTION + * Routine to obtain a color specification for full + * blue intensity and zero red and green intensities. + * + * + */ + +#include "Xlibint.h" +#include "Xcms.h" + + + +/************************************************************************ + * * + * PUBLIC INTERFACES * + * * + ************************************************************************/ + +/* + * NAME + * XcmsQueryBlue + * + * SYNOPSIS + */ + +Status +XcmsQueryBlue(ccc, target_format, pColor_ret) + XcmsCCC ccc; + XcmsColorFormat target_format; + XcmsColor *pColor_ret; +/* + * DESCRIPTION + * Returns the color specification in the target format for + * full intensity blue and zero intensity red and green. + * + * RETURNS + * Returns XcmsSuccess, if failed; otherwise XcmsFailure + * + */ +{ + XcmsColor tmp; + + tmp.format = XcmsRGBiFormat; + tmp.pixel = 0; + tmp.spec.RGBi.red = 0.0; + tmp.spec.RGBi.green = 0.0; + tmp.spec.RGBi.blue = 1.0; + if (XcmsConvertColors(ccc, &tmp, 1, target_format, NULL) != XcmsSuccess) { + return(XcmsFailure); + } + memcpy((char *)pColor_ret, (char *)&tmp, sizeof(XcmsColor)); + return(XcmsSuccess); +} diff --git a/src/xcms/QGreen.c b/src/xcms/QGreen.c new file mode 100644 index 00000000..f7858c32 --- /dev/null +++ b/src/xcms/QGreen.c @@ -0,0 +1,82 @@ +/* $Xorg: QGreen.c,v 1.3 2000/08/17 19:44:49 cpqbld Exp $ */ + +/* + * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. + * All Rights Reserved + * + * This file is a component of an X Window System-specific implementation + * of Xcms based on the TekColor Color Management System. Permission is + * hereby granted to use, copy, modify, sell, and otherwise distribute this + * software and its documentation for any purpose and without fee, provided + * that this copyright, permission, and disclaimer notice is reproduced in + * all copies of this software and in supporting documentation. TekColor + * is a trademark of Tektronix, Inc. + * + * Tektronix makes no representation about the suitability of this software + * for any purpose. It is provided "as is" and with all faults. + * + * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, + * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX 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 THE PERFORMANCE OF THIS SOFTWARE. + * + * + * NAME + * XcmsQGreen.c - Query Green + * + * DESCRIPTION + * Routine to obtain a color specification for full + * green intensity and zero red and blue intensities. + * + * + */ + +#include "Xlibint.h" +#include "Xcms.h" + + + +/************************************************************************ + * * + * PUBLIC INTERFACES * + * * + ************************************************************************/ + +/* + * NAME + * XcmsQueryGreen + * + * SYNOPSIS + */ + +Status +XcmsQueryGreen(ccc, target_format, pColor_ret) + XcmsCCC ccc; + XcmsColorFormat target_format; + XcmsColor *pColor_ret; +/* + * DESCRIPTION + * Returns the color specification in the target format for + * full intensity green and zero intensity red and blue. + * + * RETURNS + * Returns XcmsSuccess, if failed; otherwise XcmsFailure + * + */ +{ + XcmsColor tmp; + + tmp.format = XcmsRGBiFormat; + tmp.pixel = 0; + tmp.spec.RGBi.red = 0.0; + tmp.spec.RGBi.green = 1.0; + tmp.spec.RGBi.blue = 0.0; + if (XcmsConvertColors(ccc, &tmp, 1, target_format, NULL) != XcmsSuccess) { + return(XcmsFailure); + } + memcpy((char *)pColor_ret, (char *)&tmp, sizeof(XcmsColor)); + return(XcmsSuccess); +} diff --git a/src/xcms/QRed.c b/src/xcms/QRed.c new file mode 100644 index 00000000..136ebc2e --- /dev/null +++ b/src/xcms/QRed.c @@ -0,0 +1,82 @@ +/* $Xorg: QRed.c,v 1.3 2000/08/17 19:44:49 cpqbld Exp $ */ + +/* + * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. + * All Rights Reserved + * + * This file is a component of an X Window System-specific implementation + * of Xcms based on the TekColor Color Management System. Permission is + * hereby granted to use, copy, modify, sell, and otherwise distribute this + * software and its documentation for any purpose and without fee, provided + * that this copyright, permission, and disclaimer notice is reproduced in + * all copies of this software and in supporting documentation. TekColor + * is a trademark of Tektronix, Inc. + * + * Tektronix makes no representation about the suitability of this software + * for any purpose. It is provided "as is" and with all faults. + * + * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, + * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX 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 THE PERFORMANCE OF THIS SOFTWARE. + * + * + * NAME + * XcmsQRed.c - Query Red + * + * DESCRIPTION + * Routine to obtain a color specification for full + * red intensity and zero green and blue intensities. + * + * + */ + +#include "Xlibint.h" +#include "Xcms.h" + + + +/************************************************************************ + * * + * PUBLIC INTERFACES * + * * + ************************************************************************/ + +/* + * NAME + * XcmsQueryRed + * + * SYNOPSIS + */ + +Status +XcmsQueryRed(ccc, target_format, pColor_ret) + XcmsCCC ccc; + XcmsColorFormat target_format; + XcmsColor *pColor_ret; +/* + * DESCRIPTION + * Returns the color specification in the target format for + * full intensity red and zero intensity green and blue. + * + * RETURNS + * Returns XcmsSuccess, if failed; otherwise XcmsFailure + * + */ +{ + XcmsColor tmp; + + tmp.format = XcmsRGBiFormat; + tmp.pixel = 0; + tmp.spec.RGBi.red = 1.0; + tmp.spec.RGBi.green = 0.0; + tmp.spec.RGBi.blue = 0.0; + if (XcmsConvertColors(ccc, &tmp, 1, target_format, NULL) != XcmsSuccess) { + return(XcmsFailure); + } + memcpy((char *)pColor_ret, (char *)&tmp, sizeof(XcmsColor)); + return(XcmsSuccess); +} diff --git a/src/xcms/QWhite.c b/src/xcms/QWhite.c new file mode 100644 index 00000000..93d37d38 --- /dev/null +++ b/src/xcms/QWhite.c @@ -0,0 +1,82 @@ +/* $Xorg: QWhite.c,v 1.3 2000/08/17 19:44:49 cpqbld Exp $ */ + +/* + * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. + * All Rights Reserved + * + * This file is a component of an X Window System-specific implementation + * of Xcms based on the TekColor Color Management System. Permission is + * hereby granted to use, copy, modify, sell, and otherwise distribute this + * software and its documentation for any purpose and without fee, provided + * that this copyright, permission, and disclaimer notice is reproduced in + * all copies of this software and in supporting documentation. TekColor + * is a trademark of Tektronix, Inc. + * + * Tektronix makes no representation about the suitability of this software + * for any purpose. It is provided "as is" and with all faults. + * + * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, + * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX 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 THE PERFORMANCE OF THIS SOFTWARE. + * + * + * NAME + * XcmsQWhite.c - Query White + * + * DESCRIPTION + * Routine to obtain a color specification for full + * red, green, and blue intensities. + * + * + */ + +#include "Xlibint.h" +#include "Xcms.h" + + + +/************************************************************************ + * * + * PUBLIC INTERFACES * + * * + ************************************************************************/ + +/* + * NAME + * XcmsQueryWhite + * + * SYNOPSIS + */ + +Status +XcmsQueryWhite(ccc, target_format, pColor_ret) + XcmsCCC ccc; + XcmsColorFormat target_format; + XcmsColor *pColor_ret; +/* + * DESCRIPTION + * Returns the color specification in the target format for + * full intensity red, green, and blue. + * + * RETURNS + * Returns XcmsSuccess, if failed; otherwise XcmsFailure + * + */ +{ + XcmsColor tmp; + + tmp.format = XcmsRGBiFormat; + tmp.pixel = 0; + tmp.spec.RGBi.red = 1.0; + tmp.spec.RGBi.green = 1.0; + tmp.spec.RGBi.blue = 1.0; + if (XcmsConvertColors(ccc, &tmp, 1, target_format, NULL) != XcmsSuccess) { + return(XcmsFailure); + } + memcpy((char *)pColor_ret, (char *)&tmp, sizeof(XcmsColor)); + return(XcmsSuccess); +} diff --git a/src/xcms/QuCol.c b/src/xcms/QuCol.c new file mode 100644 index 00000000..d632d457 --- /dev/null +++ b/src/xcms/QuCol.c @@ -0,0 +1,76 @@ +/* $Xorg: QuCol.c,v 1.3 2000/08/17 19:44:50 cpqbld Exp $ */ + +/* + * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. + * All Rights Reserved + * + * This file is a component of an X Window System-specific implementation + * of Xcms based on the TekColor Color Management System. Permission is + * hereby granted to use, copy, modify, sell, and otherwise distribute this + * software and its documentation for any purpose and without fee, provided + * that this copyright, permission, and disclaimer notice is reproduced in + * all copies of this software and in supporting documentation. TekColor + * is a trademark of Tektronix, Inc. + * + * Tektronix makes no representation about the suitability of this software + * for any purpose. It is provided "as is" and with all faults. + * + * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, + * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX 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 THE PERFORMANCE OF THIS SOFTWARE. + * + * + * NAME + * XcmsQuCol.c + * + * DESCRIPTION + * Source for XcmsQueryColors + * + * + */ + +#include "Xlibint.h" +#include "Xcmsint.h" + + + +/************************************************************************ + * * + * PUBLIC ROUTINES * + * * + ************************************************************************/ + +/* + * NAME + * XcmsQueryColor - Query Color + * + * SYNOPSIS + */ +Status +XcmsQueryColor(dpy, colormap, pXcmsColor_in_out, result_format) + Display *dpy; + Colormap colormap; + XcmsColor *pXcmsColor_in_out; + XcmsColorFormat result_format; +/* + * DESCRIPTION + * This routine uses XQueryColor to obtain the X RGB values + * stored in the specified colormap for the specified pixel. + * The X RGB values are then converted to the target format as + * specified by the format component of the XcmsColor structure. + * + * RETURNS + * XcmsFailure if failed; + * XcmsSuccess if it succeeded. + * + * Returns a color specification of the color stored in the + * specified pixel. + */ +{ + return(_XcmsSetGetColors (XQueryColor, dpy, colormap, + pXcmsColor_in_out, 1, result_format, (Bool *) NULL)); +} diff --git a/src/xcms/QuCols.c b/src/xcms/QuCols.c new file mode 100644 index 00000000..9a35cf05 --- /dev/null +++ b/src/xcms/QuCols.c @@ -0,0 +1,75 @@ +/* $Xorg: QuCols.c,v 1.3 2000/08/17 19:44:50 cpqbld Exp $ */ + +/* + * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. + * All Rights Reserved + * + * This file is a component of an X Window System-specific implementation + * of Xcms based on the TekColor Color Management System. Permission is + * hereby granted to use, copy, modify, sell, and otherwise distribute this + * software and its documentation for any purpose and without fee, provided + * that this copyright, permission, and disclaimer notice is reproduced in + * all copies of this software and in supporting documentation. TekColor + * is a trademark of Tektronix, Inc. + * + * Tektronix makes no representation about the suitability of this software + * for any purpose. It is provided "as is" and with all faults. + * + * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, + * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX 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 THE PERFORMANCE OF THIS SOFTWARE. + * + * + * NAME + * XcmsQuCol.c + * + * DESCRIPTION + * Source for XcmsQueryColors + * + * + */ + +#include "Xlibint.h" +#include "Xcmsint.h" + + +/************************************************************************ + * * + * PUBLIC ROUTINES * + * * + ************************************************************************/ +/* + * NAME + * XcmsQueryColors - Query Colors + * + * SYNOPSIS + */ +Status +XcmsQueryColors(dpy, colormap, pXcmsColors_in_out, nColors, result_format) + Display *dpy; + Colormap colormap; + XcmsColor *pXcmsColors_in_out; + unsigned int nColors; + XcmsColorFormat result_format; +/* + * DESCRIPTION + * This routine uses XQueryColors to obtain the X RGB values + * stored in the specified colormap for the specified pixels. + * The X RGB values are then converted to the target format as + * specified by the format component of the XcmsColor structure. + * + * RETURNS + * XcmsFailure if failed; + * XcmsSuccess if it succeeded. + * + * Returns the color specifications of the colors stored in the + * specified pixels. + */ +{ + return(_XcmsSetGetColors (XQueryColors, dpy, colormap, + pXcmsColors_in_out, nColors, result_format, (Bool *) NULL)); +} diff --git a/src/xcms/SetCCC.c b/src/xcms/SetCCC.c new file mode 100644 index 00000000..d58daf8a --- /dev/null +++ b/src/xcms/SetCCC.c @@ -0,0 +1,150 @@ +/* $Xorg: SetCCC.c,v 1.3 2000/08/17 19:44:52 cpqbld Exp $ */ + +/* + * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. + * All Rights Reserved + * + * This file is a component of an X Window System-specific implementation + * of Xcms based on the TekColor Color Management System. Permission is + * hereby granted to use, copy, modify, sell, and otherwise distribute this + * software and its documentation for any purpose and without fee, provided + * that this copyright, permission, and disclaimer notice is reproduced in + * all copies of this software and in supporting documentation. TekColor + * is a trademark of Tektronix, Inc. + * + * Tektronix makes no representation about the suitability of this software + * for any purpose. It is provided "as is" and with all faults. + * + * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, + * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX 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 THE PERFORMANCE OF THIS SOFTWARE. + * + * + * NAME + * XcmsSetCCC.c - Color Conversion Context Setting Routines + * + * DESCRIPTION + * Routines to set components of a Color Conversion + * Context structure. + * + * + */ + +#include "Xlibint.h" +#include "Xcms.h" + + + +/************************************************************************ + * * + * PUBLIC INTERFACES * + * * + ************************************************************************/ + +/* + * NAME + * XcmsSetWhitePoint + * + * SYNOPSIS + */ + +Status +XcmsSetWhitePoint(ccc, pColor) + XcmsCCC ccc; + XcmsColor *pColor; +/* + * DESCRIPTION + * Sets the Client White Point in the specified CCC. + * + * RETURNS + * Returns XcmsSuccess if succeeded; otherwise XcmsFailure. + * + */ +{ + if (pColor == NULL || pColor->format == XcmsUndefinedFormat) { + ccc->clientWhitePt.format = XcmsUndefinedFormat; + } else if (pColor->format != XcmsCIEXYZFormat && + pColor->format != XcmsCIEuvYFormat && + pColor->format != XcmsCIExyYFormat) { + return(XcmsFailure); + } else { + memcpy((char *)&ccc->clientWhitePt, (char *)pColor, sizeof(XcmsColor)); + } + return(XcmsSuccess); +} + + +/* + * NAME + * XcmsSetCompressionProc + * + * SYNOPSIS + */ + +XcmsCompressionProc +#if NeedFunctionPrototypes +XcmsSetCompressionProc( + XcmsCCC ccc, + XcmsCompressionProc compression_proc, + XPointer client_data) +#else +XcmsSetCompressionProc(ccc, compression_proc, client_data) + XcmsCCC ccc; + XcmsCompressionProc compression_proc; + XPointer client_data; +#endif +/* + * DESCRIPTION + * Set the specified CCC's compression function and client data. + * + * RETURNS + * Returns the old compression function. + * + */ +{ + XcmsCompressionProc old = ccc->gamutCompProc; + + ccc->gamutCompProc = compression_proc; + ccc->gamutCompClientData = client_data; + return(old); +} + + +/* + * NAME + * XcmsSetWhiteAdjustProc + * + * SYNOPSIS + */ + +XcmsWhiteAdjustProc +#if NeedFunctionPrototypes +XcmsSetWhiteAdjustProc( + XcmsCCC ccc, + XcmsWhiteAdjustProc white_adjust_proc, + XPointer client_data ) +#else +XcmsSetWhiteAdjustProc(ccc, white_adjust_proc, client_data) + XcmsCCC ccc; + XcmsWhiteAdjustProc white_adjust_proc; + XPointer client_data; +#endif +/* + * DESCRIPTION + * Set the specified CCC's white_adjust function and client data. + * + * RETURNS + * Returns the old white_adjust function. + * + */ +{ + XcmsWhiteAdjustProc old = ccc->whitePtAdjProc; + + ccc->whitePtAdjProc = white_adjust_proc; + ccc->whitePtAdjClientData = client_data; + return(old); +} diff --git a/src/xcms/SetGetCols.c b/src/xcms/SetGetCols.c new file mode 100644 index 00000000..5ee68985 --- /dev/null +++ b/src/xcms/SetGetCols.c @@ -0,0 +1,201 @@ +/* $Xorg: SetGetCols.c,v 1.3 2000/08/17 19:44:54 cpqbld Exp $ */ + +/* + * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. + * All Rights Reserved + * + * This file is a component of an X Window System-specific implementation + * of Xcms based on the TekColor Color Management System. Permission is + * hereby granted to use, copy, modify, sell, and otherwise distribute this + * software and its documentation for any purpose and without fee, provided + * that this copyright, permission, and disclaimer notice is reproduced in + * all copies of this software and in supporting documentation. TekColor + * is a trademark of Tektronix, Inc. + * + * Tektronix makes no representation about the suitability of this software + * for any purpose. It is provided "as is" and with all faults. + * + * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, + * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX 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 THE PERFORMANCE OF THIS SOFTWARE. + * + * + * NAME + * XcmsSetGet.c + * + * DESCRIPTION + * Source for _XcmsSetGetColors() + * + * + */ + +/* + * EXTERNAL INCLUDES + * Include files that must be exported to any package or + * program using this package. + */ +#include "Xlibint.h" +#include "Xcmsint.h" + + +/* + * EXTERNS + */ + +extern void _XcmsRGB_to_XColor(); +extern void _XColor_to_XcmsRGB(); + + + +/************************************************************************ + * * + * API PRIVATE ROUTINES * + * * + ************************************************************************/ + +/* + * NAME + * XcmsSetColors - + * + * SYNOPSIS + */ +Status +_XcmsSetGetColors(xColorProc, dpy, cmap, pColors_in_out, nColors, + result_format, pCompressed) + Status (*xColorProc)(); + Display *dpy; + Colormap cmap; + XcmsColor *pColors_in_out; + unsigned int nColors; + XcmsColorFormat result_format; + Bool *pCompressed; +/* + * DESCRIPTION + * Routine containing code common to: + * XcmsAllocColor + * XcmsQueryColor + * XcmsQueryColors + * XcmsStoreColor + * XcmsStoreColors + * + * RETURNS + * XcmsFailure if failed; + * XcmsSuccess if it succeeded without gamut compression; + * XcmsSuccessWithCompression if it succeeded with gamut + * compression; + */ +{ + XcmsCCC ccc; + XColor *pXColors_in_out; + Status retval = XcmsSuccess; + + /* + * Argument Checking + * 1. Assume xColorProc is correct + * 2. Insure ccc not NULL + * 3. Assume cmap correct (should be checked by Server) + * 4. Insure pColors_in_out valid + * 5. Assume method_in is valid (should be checked by Server) + * 6. Insure nColors > 0 + */ + + if (dpy == NULL) { + return(XcmsFailure); + } + + if (nColors == 0) { + return(XcmsSuccess); + } + + if (result_format == XcmsUndefinedFormat) { + return(XcmsFailure); + } + + if (!((*xColorProc == XAllocColor) || (*xColorProc == XStoreColor) + || (*xColorProc == XStoreColors) || (*xColorProc == XQueryColor) + || (*xColorProc == XQueryColors))) { + return(XcmsFailure); + } + + if ((ccc = XcmsCCCOfColormap(dpy, cmap)) == (XcmsCCC)NULL) { + return(XcmsFailure); + } + + if ((*xColorProc == XAllocColor) || (*xColorProc == XStoreColor) + || (*xColorProc == XQueryColor)) { + nColors = 1; + } + + /* + * Allocate space for XColors + */ + if ((pXColors_in_out = (XColor *)Xcalloc(nColors, sizeof(XColor))) == + NULL) { + return(XcmsFailure); + } + + if ((*xColorProc == XQueryColor) || (*xColorProc == XQueryColors)) { + goto Query; + } + /* + * Convert to RGB, adjusting for white point differences if necessary. + */ + if ((retval = XcmsConvertColors(ccc, pColors_in_out, nColors, XcmsRGBFormat, + pCompressed)) == XcmsFailure) { + return(XcmsFailure); + } + +Query: + /* + * Convert XcmsColor to XColor structures + */ + _XcmsRGB_to_XColor(pColors_in_out, pXColors_in_out, nColors); + + /* + * Now make appropriate X Call + */ + if (*xColorProc == XAllocColor) { + if ((*xColorProc)(ccc->dpy, cmap, pXColors_in_out) == 0) { + Xfree((char *)pXColors_in_out); + return(XcmsFailure); + } + } else if ((*xColorProc == XQueryColor) || (*xColorProc == XStoreColor)) { + /* Note: XQueryColor and XStoreColor do not return any Status */ + (*xColorProc)(ccc->dpy, cmap, pXColors_in_out); + } else if ((*xColorProc == XQueryColors) || (*xColorProc == XStoreColors)){ + /* Note: XQueryColors and XStoreColors do not return any Status */ + (*xColorProc)(ccc->dpy, cmap, pXColors_in_out, nColors); + } else { + Xfree((char *)pXColors_in_out); + return(XcmsFailure); + } + + if ((*xColorProc == XStoreColor) || (*xColorProc == XStoreColors)) { + Xfree((char *)pXColors_in_out); + return(retval); + } + + /* + * Now, convert returned XColor(i.e., rgb) to XcmsColor structures + */ + _XColor_to_XcmsRGB(ccc, pXColors_in_out, pColors_in_out, nColors); + Xfree((char *)pXColors_in_out); + + /* + * Then, convert XcmsColor structures to the original specification + * format. Note that we must use NULL instead of passing + * pCompressed. + */ + + if (result_format != XcmsRGBFormat) { + if (XcmsConvertColors(ccc, pColors_in_out, nColors, result_format, + (Bool *) NULL) == XcmsFailure) { + return(XcmsFailure); + } + } + return(retval); +} diff --git a/src/xcms/StCol.c b/src/xcms/StCol.c new file mode 100644 index 00000000..b6229f98 --- /dev/null +++ b/src/xcms/StCol.c @@ -0,0 +1,79 @@ +/* $Xorg: StCol.c,v 1.3 2000/08/17 19:44:55 cpqbld Exp $ */ + +/* + * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. + * All Rights Reserved + * + * This file is a component of an X Window System-specific implementation + * of Xcms based on the TekColor Color Management System. Permission is + * hereby granted to use, copy, modify, sell, and otherwise distribute this + * software and its documentation for any purpose and without fee, provided + * that this copyright, permission, and disclaimer notice is reproduced in + * all copies of this software and in supporting documentation. TekColor + * is a trademark of Tektronix, Inc. + * + * Tektronix makes no representation about the suitability of this software + * for any purpose. It is provided "as is" and with all faults. + * + * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, + * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX 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 THE PERFORMANCE OF THIS SOFTWARE. + * + * + * NAME + * XcmsStCol.c + * + * DESCRIPTION + * Source for XcmsStoreColor + * + * + */ + +#include "Xlibint.h" +#include "Xcmsint.h" + + +/************************************************************************ + * * + * PUBLIC ROUTINES * + * * + ************************************************************************/ + +/* + * NAME + * XcmsStoreColor - Store Color + * + * SYNOPSIS + */ +Status +XcmsStoreColor(dpy, colormap, pColor_in) + Display *dpy; + Colormap colormap; + XcmsColor *pColor_in; +/* + * DESCRIPTION + * Given a device-dependent or device-independent color + * specification, this routine will convert it to X RGB + * values then use it in a call to XStoreColor. + * + * RETURNS + * XcmsFailure if failed; + * XcmsSuccess if it succeeded without gamut compression; + * XcmsSuccessWithCompression if it succeeded with gamut + * compression; + * + * Since XStoreColor has no return value this routine + * does not return the color specification of the color actually + * stored. + */ +{ + XcmsColor tmpColor; + + tmpColor = *pColor_in; + return(_XcmsSetGetColors (XStoreColor, dpy, colormap, + &tmpColor, 1, XcmsRGBFormat, (Bool *) NULL)); +} diff --git a/src/xcms/StCols.c b/src/xcms/StCols.c new file mode 100644 index 00000000..1e833c34 --- /dev/null +++ b/src/xcms/StCols.c @@ -0,0 +1,110 @@ +/* $Xorg: StCols.c,v 1.3 2000/08/17 19:44:56 cpqbld Exp $ */ + +/* + * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. + * All Rights Reserved + * + * This file is a component of an X Window System-specific implementation + * of Xcms based on the TekColor Color Management System. Permission is + * hereby granted to use, copy, modify, sell, and otherwise distribute this + * software and its documentation for any purpose and without fee, provided + * that this copyright, permission, and disclaimer notice is reproduced in + * all copies of this software and in supporting documentation. TekColor + * is a trademark of Tektronix, Inc. + * + * Tektronix makes no representation about the suitability of this software + * for any purpose. It is provided "as is" and with all faults. + * + * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, + * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX 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 THE PERFORMANCE OF THIS SOFTWARE. + * + * + * NAME + * XcmsStCols.c + * + * DESCRIPTION + * Source for XcmsStoreColors + * + * + */ + +#include "Xlibint.h" +#include "Xcmsint.h" + + +/************************************************************************ + * * + * PUBLIC ROUTINES * + * * + ************************************************************************/ + +/* + * NAME + * XcmsStoreColors - Store Colors + * + * SYNOPSIS + */ +Status +XcmsStoreColors(dpy, colormap, pColors_in, + nColors, pCompressed) + Display *dpy; + Colormap colormap; + XcmsColor *pColors_in; + unsigned int nColors; + Bool *pCompressed; +/* + * DESCRIPTION + * Given device-dependent or device-independent color + * specifications, this routine will convert them to X RGB + * values then use it in a call to XStoreColors. + * + * RETURNS + * XcmsFailure if failed; + * XcmsSuccess if it succeeded without gamut compression; + * XcmsSuccessWithCompression if it succeeded with gamut + * compression; + * + * Since XStoreColors has no return value, this routine + * does not return color specifications of the colors actually + * stored. + */ +{ + XcmsColor Color1; + XcmsColor *pColors_tmp; + Status retval; + + /* + * Make copy of array of color specifications so we don't + * overwrite the contents. + */ + if (nColors > 1) { + pColors_tmp = (XcmsColor *) Xmalloc(nColors * sizeof(XcmsColor)); + } else { + pColors_tmp = &Color1; + } + memcpy((char *)pColors_tmp, (char *)pColors_in, + nColors * sizeof(XcmsColor)); + + /* + * Call routine to store colors using the copied color structures + */ + retval = _XcmsSetGetColors (XStoreColors, dpy, colormap, + pColors_tmp, nColors, XcmsRGBFormat, pCompressed); + + /* + * Free copies as needed. + */ + if (nColors > 1) { + Xfree((char *)pColors_tmp); + } + + /* + * Ah, finally return. + */ + return(retval); +} diff --git a/src/xcms/UNDEFINED.c b/src/xcms/UNDEFINED.c new file mode 100644 index 00000000..a4e05551 --- /dev/null +++ b/src/xcms/UNDEFINED.c @@ -0,0 +1,102 @@ +/* $Xorg: UNDEFINED.c,v 1.3 2000/08/17 19:44:57 cpqbld Exp $ */ + +/* + * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. + * All Rights Reserved + * + * This file is a component of an X Window System-specific implementation + * of Xcms based on the TekColor Color Management System. Permission is + * hereby granted to use, copy, modify, sell, and otherwise distribute this + * software and its documentation for any purpose and without fee, provided + * that this copyright, permission, and disclaimer notice is reproduced in + * all copies of this software and in supporting documentation. TekColor + * is a trademark of Tektronix, Inc. + * + * Tektronix makes no representation about the suitability of this software + * for any purpose. It is provided "as is" and with all faults. + * + * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, + * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX 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 THE PERFORMANCE OF THIS SOFTWARE. + * + * + * + * NAME + * UNDEFINED.c + * + * DESCRIPTION + * UNDEFINED Color Space + * + * + */ + +#include "Xlibint.h" +#include "Xcmsint.h" + +/* + * FORWARD DECLARATIONS + */ +static int ReturnZero(); + + +/* + * LOCALS VARIABLES + */ + +static Status (*(Fl_ReturnZero[]))() = { + ReturnZero, + NULL +}; + + + + +/* + * GLOBALS + * Variables declared in this package that are allowed + * to be used globally. + */ + /* + * UNDEFINED Color Space + */ +XcmsColorSpace XcmsUNDEFINEDColorSpace = + { + "undefined", /* prefix */ + XcmsUndefinedFormat, /* id */ + ReturnZero, /* parseString */ + Fl_ReturnZero, /* to_CIEXYZ */ + Fl_ReturnZero /* from_CIEXYZ */ + }; + + + +/************************************************************************ + * * + * PRIVATE ROUTINES * + * * + ************************************************************************/ + +/* + * NAME + * ReturnZero + * + * SYNOPSIS + */ +/* ARGSUSED */ +static int +ReturnZero() +/* + * DESCRIPTION + * Does nothing. + * + * RETURNS + * 0 + * + */ +{ + return(0); +} diff --git a/src/xcms/XRGB.c b/src/xcms/XRGB.c new file mode 100644 index 00000000..7e5b7f84 --- /dev/null +++ b/src/xcms/XRGB.c @@ -0,0 +1,245 @@ +/* $Xorg: XRGB.c,v 1.3 2000/08/17 19:45:04 cpqbld Exp $ */ + +/* + * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. + * All Rights Reserved + * + * This file is a component of an X Window System-specific implementation + * of Xcms based on the TekColor Color Management System. Permission is + * hereby granted to use, copy, modify, sell, and otherwise distribute this + * software and its documentation for any purpose and without fee, provided + * that this copyright, permission, and disclaimer notice is reproduced in + * all copies of this software and in supporting documentation. TekColor + * is a trademark of Tektronix, Inc. + * + * Tektronix makes no representation about the suitability of this software + * for any purpose. It is provided "as is" and with all faults. + * + * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, + * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX 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 THE PERFORMANCE OF THIS SOFTWARE. + * + * + * NAME + * XcmsRtoX.c + * + * DESCRIPTION + * Convert color specifications in XcmsRGB format in one array of + * XcmsColor structures to RGB in an array of XColor structures. + * + * + */ + +#include "Xlibint.h" +#include "Xcmsint.h" + +#ifdef __STDC__ +#define Const const +#else +#define Const /**/ +#endif + +/* + * LOCAL VARIABLES + */ + +static unsigned short Const MASK[17] = { + 0x0000, /* 0 bitsPerRGB */ + 0x8000, /* 1 bitsPerRGB */ + 0xc000, /* 2 bitsPerRGB */ + 0xe000, /* 3 bitsPerRGB */ + 0xf000, /* 4 bitsPerRGB */ + 0xf800, /* 5 bitsPerRGB */ + 0xfc00, /* 6 bitsPerRGB */ + 0xfe00, /* 7 bitsPerRGB */ + 0xff00, /* 8 bitsPerRGB */ + 0xff80, /* 9 bitsPerRGB */ + 0xffc0, /* 10 bitsPerRGB */ + 0xffe0, /* 11 bitsPerRGB */ + 0xfff0, /* 12 bitsPerRGB */ + 0xfff8, /* 13 bitsPerRGB */ + 0xfffc, /* 14 bitsPerRGB */ + 0xfffe, /* 15 bitsPerRGB */ + 0xffff /* 16 bitsPerRGB */ +}; + + + +/************************************************************************ + * * + * API PRIVATE ROUTINES * + * * + ************************************************************************/ + +/* + * NAME + * _XcmsRGB_to_XColor - + * + * SYNOPSIS + */ +void +_XcmsRGB_to_XColor(pColors, pXColors, nColors) + XcmsColor *pColors; + XColor *pXColors; + unsigned int nColors; +/* + * DESCRIPTION + * Translates a color specification in XcmsRGBFormat in a XcmsColor + * structure to an XColor structure. + * + * RETURNS + * void. + */ +{ + for (; nColors--; pXColors++, pColors++) { + pXColors->pixel = pColors->pixel; + pXColors->red = pColors->spec.RGB.red; + pXColors->green = pColors->spec.RGB.green; + pXColors->blue = pColors->spec.RGB.blue; + pXColors->flags = (DoRed | DoGreen | DoBlue); + } +} + + +/* + * NAME + * _XColor_to_XcmsRGB + * + * SYNOPSIS + */ +void +_XColor_to_XcmsRGB(ccc, pXColors, pColors, nColors) + XcmsCCC ccc; + XColor *pXColors; + XcmsColor *pColors; + unsigned int nColors; +/* + * DESCRIPTION + * Translates an RGB color specification in an XColor + * structure to an XcmsRGB structure. + * + * IMPORTANT NOTE: Bit replication that may have been caused + * with ResolveColor() routine in the X Server is undone + * here if requested! For example, if red = 0xcaca and the + * bits_per_rgb is 8, then spec.RGB.red will be 0xca00. + * + * RETURNS + * void + */ +{ + int bits_per_rgb = ccc->visual->bits_per_rgb; + + for (; nColors--; pXColors++, pColors++) { + pColors->spec.RGB.red = (pXColors->red & MASK[bits_per_rgb]); + pColors->spec.RGB.green = (pXColors->green & MASK[bits_per_rgb]); + pColors->spec.RGB.blue = (pXColors->blue & MASK[bits_per_rgb]); + pColors->format = XcmsRGBFormat; + pColors->pixel = pXColors->pixel; + } +} + + +/* + * NAME + * _XcmsResolveColor + * + * SYNOPSIS + */ +void +_XcmsResolveColor(ccc, pXcmsColor) + XcmsCCC ccc; + XcmsColor *pXcmsColor; +/* + * DESCRIPTION + * Uses the X Server ResolveColor() algorithm to + * modify values to closest values supported by hardware. + * Old algorithm simply masked low-order bits. The new algorithm + * has the effect of replicating significant bits into lower order + * bits in order to stretch the hardware value into all 16 bits. + * + * On a display with N-bit DACs, the "hardware" color is computed as: + * + * ((unsignedlong)(ClientValue >> (16-N)) * 0xFFFF) / ((1 << N) - 1) + * + * + * RETURNS + * void. + */ +{ + int shift; + int max_color; + + shift = 16 - ccc->visual->bits_per_rgb; + max_color = (1 << ccc->visual->bits_per_rgb) - 1; + + + pXcmsColor->spec.RGB.red = + ((unsigned long)(pXcmsColor->spec.RGB.red >> shift) * 0xFFFF) + / max_color; + pXcmsColor->spec.RGB.green = + ((unsigned long)(pXcmsColor->spec.RGB.green >> shift) * 0xFFFF) + / max_color; + pXcmsColor->spec.RGB.blue = + ((unsigned long)(pXcmsColor->spec.RGB.blue >> shift) * 0xFFFF) + / max_color; +} + + +/* + * NAME + * _XcmsUnresolveColor + * + * SYNOPSIS + */ +void +_XcmsUnresolveColor(ccc, pColor) + XcmsCCC ccc; + XcmsColor *pColor; +/* + * DESCRIPTION + * Masks out insignificant bits. + * + * RETURNS + * void. + * + * ASSUMPTIONS + * format == XcmsRGBFormat + */ +{ + int bits_per_rgb = ccc->visual->bits_per_rgb; + + pColor->spec.RGB.red &= MASK[bits_per_rgb]; + pColor->spec.RGB.green &= MASK[bits_per_rgb]; + pColor->spec.RGB.blue &= MASK[bits_per_rgb]; +} + + +/* + * NAME + * _XUnresolveColor + * + * SYNOPSIS + */ +void +_XUnresolveColor(ccc, pXColor) + XcmsCCC ccc; + XColor *pXColor; +/* + * DESCRIPTION + * Masks out insignificant bits. + * + * RETURNS + * void. + */ +{ + int bits_per_rgb = ccc->visual->bits_per_rgb; + + pXColor->red &= MASK[bits_per_rgb]; + pXColor->green &= MASK[bits_per_rgb]; + pXColor->blue &= MASK[bits_per_rgb]; +} + diff --git a/src/xcms/XYZ.c b/src/xcms/XYZ.c new file mode 100644 index 00000000..a06b2132 --- /dev/null +++ b/src/xcms/XYZ.c @@ -0,0 +1,192 @@ +/* $Xorg: XYZ.c,v 1.3 2000/08/17 19:45:04 cpqbld Exp $ */ + +/* + * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. + * All Rights Reserved + * + * This file is a component of an X Window System-specific implementation + * of XCMS based on the TekColor Color Management System. Permission is + * hereby granted to use, copy, modify, sell, and otherwise distribute this + * software and its documentation for any purpose and without fee, provided + * that this copyright, permission, and disclaimer notice is reproduced in + * all copies of this software and in supporting documentation. TekColor + * is a trademark of Tektronix, Inc. + * + * Tektronix makes no representation about the suitability of this software + * for any purpose. It is provided "as is" and with all faults. + * + * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, + * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX 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 THE PERFORMANCE OF THIS SOFTWARE. + * + * + * + * NAME + * CIEXYZ.c + * + * DESCRIPTION + * CIE XYZ Color Space + * + * + */ + +#include <X11/Xos.h> +#include "Xlibint.h" +#include "Xcmsint.h" + + +/* + * EXTERNS + * External declarations required locally to this package + * that are not already declared in any of the included header + * files (external includes or internal includes). + */ +extern char _XcmsCIEXYZ_prefix[]; + +/* + * DEFINES + * Internal definitions that need NOT be exported to any package + * or program using this package. + */ +#ifdef DBL_EPSILON +# define XMY_DBL_EPSILON DBL_EPSILON +#else +# define XMY_DBL_EPSILON 0.00001 +#endif + +/* + * FORWARD DECLARATIONS + */ +static int CIEXYZ_ParseString(); +Status _XcmsCIEXYZ_ValidSpec(); + + +/* + * LOCALS VARIABLES + */ + +static XcmsConversionProc Fl_CIEXYZ_to_CIEXYZ[] = { + NULL +}; + + + +/* + * GLOBALS + * Variables declared in this package that are allowed + * to be used globally. + */ + /* + * CIE XYZ Color Space + */ +XcmsColorSpace XcmsCIEXYZColorSpace = + { + _XcmsCIEXYZ_prefix, /* prefix */ + XcmsCIEXYZFormat, /* id */ + CIEXYZ_ParseString, /* parseString */ + Fl_CIEXYZ_to_CIEXYZ, /* to_CIEXYZ */ + Fl_CIEXYZ_to_CIEXYZ, /* from_CIEXYZ */ + 1 + }; + + +/************************************************************************ + * * + * PRIVATE ROUTINES * + * * + ************************************************************************/ + +/* + * NAME + * CIEXYZ_ParseString + * + * SYNOPSIS + */ +static int +CIEXYZ_ParseString(spec, pColor) + register char *spec; + XcmsColor *pColor; +/* + * DESCRIPTION + * This routines takes a string and attempts to convert + * it into a XcmsColor structure with XcmsCIEXYZFormat. + * The assumed CIEXYZ string syntax is: + * CIEXYZ:<X>/<Y>/<Z> + * Where X, Y, and Z are in string input format for floats + * consisting of: + * a. an optional sign + * b. a string of numbers possibly containing a decimal point, + * c. an optional exponent field containing an 'E' or 'e' + * followed by a possibly signed integer string. + * + * RETURNS + */ +{ + int n; + char *pchar; + + if ((pchar = strchr(spec, ':')) == NULL) { + return(XcmsFailure); + } + n = (int)(pchar - spec); + + /* + * Check for proper prefix. + */ + if (strncmp(spec, _XcmsCIEXYZ_prefix, n) != 0) { + return(XcmsFailure); + } + + /* + * Attempt to parse the value portion. + */ + if (sscanf(spec + n + 1, "%lf/%lf/%lf", + &pColor->spec.CIEXYZ.X, + &pColor->spec.CIEXYZ.Y, + &pColor->spec.CIEXYZ.Z) != 3) { + return(XcmsFailure); + } + pColor->format = XcmsCIEXYZFormat; + pColor->pixel = 0; + return(_XcmsCIEXYZ_ValidSpec(pColor)); +} + + +/************************************************************************ + * * + * PUBLIC ROUTINES * + * * + ************************************************************************/ + +/* + * NAME + * XcmsCIELab_ValidSpec + * + * SYNOPSIS + */ +Status +_XcmsCIEXYZ_ValidSpec(pColor) + XcmsColor *pColor; +/* + * DESCRIPTION + * Checks if color specification valid for CIE XYZ + * + * RETURNS + * XcmsFailure if invalid, + * XcmsSuccess if valid. + * + */ +{ + if (pColor->format != XcmsCIEXYZFormat + || + (pColor->spec.CIEXYZ.Y < 0.0 - XMY_DBL_EPSILON) + || + (pColor->spec.CIEXYZ.Y > 1.0 + XMY_DBL_EPSILON)) { + return(XcmsFailure); + } + return(XcmsSuccess); +} diff --git a/src/xcms/Xcms.txt b/src/xcms/Xcms.txt new file mode 100644 index 00000000..c27fd8f4 --- /dev/null +++ b/src/xcms/Xcms.txt @@ -0,0 +1,61 @@ +/* + * (c) Copyright 1990 1991 Tektronix Inc. + * 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 Tektronix not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. + * + * Tektronix disclaims all warranties with regard to this software, including + * all implied warranties of merchantability and fitness, in no event shall + * Tektronix 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. + * + * + * NAME + * Xcms.txt + * + * DESCRIPTION + * Sample Color Name Database + * + */ + + +This device-independent color name database is provided just as an example. +There are no claims that these color specifications are or should be bound +to the corresponding color name. + +As you can see, the start of the database is indicated by "XCMS_COLORDB_START". +Anything before this is assumed to be comments. The "0.1" indicates the +version number of the format/syntax used in this file. The color name is +delimited from the color specification by one or more tabs. + +XCMS_COLORDB_START 0.1 +red CIEXYZ:0.371298/0.201443/0.059418 +green CIEXYZ:0.321204/0.660070/0.159833 +blue CIEXYZ:0.279962/0.160195/1.210705 +aquamarine CIEXYZ:0.34672401/0.54832153/0.44658871 +cadet blue CIEXYZ:0.22601070/0.28905571/0.47233452 +cornflower blue CIEXYZ:0.05658276/0.04476296/0.17063955 +navy blue CIEXYZ:0.06713718/0.03366278/0.31293880 +navy CIEXYZ:0.06713718/0.03366278/0.31293880 +brown CIEXYZ:0.08443233/0.06011398/0.01840693 +gray0 TekHVC:0.0/0.0/0.0 +gray10 TekHVC:0.0/10.0/0.0 +gray20 TekHVC:0.0/20.0/0.0 +gray30 TekHVC:0.0/30.0/0.0 +gray40 TekHVC:0.0/40.0/0.0 +gray50 TekHVC:0.0/50.0/0.0 +gray60 TekHVC:0.0/60.0/0.0 +gray70 TekHVC:0.0/70.0/0.0 +gray80 TekHVC:0.0/80.0/0.0 +gray90 TekHVC:0.0/90.0/0.0 +gray100 TekHVC:0.0/100.0/0.0 +XCMS_COLORDB_END diff --git a/src/xcms/Xcmsint.h b/src/xcms/Xcmsint.h new file mode 100644 index 00000000..68cd1b7b --- /dev/null +++ b/src/xcms/Xcmsint.h @@ -0,0 +1,246 @@ +/* $Xorg: Xcmsint.h,v 1.3 2000/08/17 19:45:05 cpqbld Exp $ */ + +/* + * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. + * All Rights Reserved + * + * This file is a component of an X Window System-specific implementation + * of Xcms based on the TekColor Color Management System. Permission is + * hereby granted to use, copy, modify, sell, and otherwise distribute this + * software and its documentation for any purpose and without fee, provided + * that this copyright, permission, and disclaimer notice is reproduced in + * all copies of this software and in supporting documentation. TekColor + * is a trademark of Tektronix, Inc. + * + * Tektronix makes no representation about the suitability of this software + * for any purpose. It is provided "as is" and with all faults. + * + * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, + * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX 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 THE PERFORMANCE OF THIS SOFTWARE. + * + * + * DESCRIPTION + * Private include file for Color Management System. + * (i.e., for API internal use only) + * + */ +#ifndef _XCMSINT_H_ +#define _XCMSINT_H_ + +#include <X11/Xcms.h> + +/* + * DEFINES + */ + + /* + * Private Status Value + */ +#define _XCMS_NEWNAME -1 + + /* + * Color Space ID's are of XcmsColorFormat type. + * + * bit 31 + * 0 == Device-Independent + * 1 == Device-Dependent + * + * bit 30: + * 0 == Registered with X Consortium + * 1 == Unregistered + */ +#define XCMS_DD_ID(id) ((id) & (XcmsColorFormat)0x80000000) +#define XCMS_DI_ID(id) (!((id) & (XcmsColorFormat)0x80000000)) +#define XCMS_UNREG_ID(id) ((id) & (XcmsColorFormat)0x40000000) +#define XCMS_REG_ID(id) (!((id) & (XcmsColorFormat)0x40000000)) +#define XCMS_FIRST_REG_DI_ID (XcmsColorFormat)0x00000001 +#define XCMS_FIRST_UNREG_DI_ID (XcmsColorFormat)0x40000000 +#define XCMS_FIRST_REG_DD_ID (XcmsColorFormat)0x80000000 +#define XCMS_FIRST_UNREG_DD_ID (XcmsColorFormat)0xc0000000 + +/* + * TYPEDEFS + */ + + /* + * Structure for caching Colormap info. + * This is provided for the Xlib modifications to: + * XAllocNamedColor() + * XLookupColor() + * XParseColor() + * XStoreNamedColor() + */ +typedef struct _XcmsCmapRec { + Colormap cmapID; + Display *dpy; + Window windowID; + Visual *visual; + struct _XcmsCCC *ccc; + struct _XcmsCmapRec *pNext; +} XcmsCmapRec; + + /* + * Intensity Record (i.e., value / intensity tuple) + */ +typedef struct _IntensityRec { + unsigned short value; + XcmsFloat intensity; +} IntensityRec; + + /* + * Intensity Table + */ +typedef struct _IntensityTbl { + IntensityRec *pBase; + unsigned int nEntries; +} IntensityTbl; + + /* + * Structure for storing per-Visual Intensity Tables (aka gamma maps). + */ +typedef struct _XcmsIntensityMap { + VisualID visualID; + XPointer screenData; /* pointer to corresponding Screen Color*/ + /* Characterization Data */ + void (*pFreeScreenData)(); /* Function that frees a Screen */ + /* structure. */ + struct _XcmsIntensityMap *pNext; +} XcmsIntensityMap; + + + /* + * Structure for storing "registered" color space prefix/ID + */ +typedef struct _XcmsRegColorSpaceEntry { + char *prefix; /* Color Space prefix (e.g., "CIEXYZ:") */ + XcmsColorFormat id; /* Color Space ID (e.g., XcmsCIEXYZFormat) */ +} XcmsRegColorSpaceEntry; + + + /* + * Xcms Per Display (i.e. connection) related data + */ +typedef struct _XcmsPerDpyInfo { + + XcmsCCC paDefaultCCC; /* based on default visual of screen */ + /* + * Pointer to an array of XcmsCCC structures, one for + * each screen. + */ + XcmsCmapRec *pClientCmaps; /* Pointer to linked list of XcmsCmapRec's */ + +} XcmsPerDpyInfo, *XcmsPerDpyInfoPtr; + +/* + * DEFINES + */ + +#define XDCCC_NUMBER 0x8000000L /* 2**27 per XDCCC */ + +#ifdef GRAY +#define XDCCC_SCREENWHITEPT_ATOM_NAME "XDCCC_GRAY_SCREENWHITEPOINT" +#define XDCCC_GRAY_CORRECT_ATOM_NAME "XDCCC_GRAY_CORRECTION" +#endif /* GRAY */ + +#ifndef _ConversionValues +typedef struct _ConversionValues { + IntensityTbl IntensityTbl; +} ConversionValues; +#endif + +#ifdef GRAY +typedef struct { + IntensityTbl *IntensityTbl; +} GRAY_SCCData; +#endif /* GRAY */ + +/* + * DEFINES + */ + +#define XDCCC_MATRIX_ATOM_NAME "XDCCC_LINEAR_RGB_MATRICES" +#define XDCCC_CORRECT_ATOM_NAME "XDCCC_LINEAR_RGB_CORRECTION" + +typedef struct { + XcmsFloat XYZtoRGBmatrix[3][3]; + XcmsFloat RGBtoXYZmatrix[3][3]; + IntensityTbl *pRedTbl; + IntensityTbl *pGreenTbl; + IntensityTbl *pBlueTbl; +} LINEAR_RGB_SCCData; + +/* + * DESCRIPTION + * Include file for defining the math macros used in the + * XCMS source. Instead of using math library routines + * directly, XCMS uses macros so that based on the + * definitions here, vendors and sites can specify exactly + * what routine will be called (those from libm.a or their + * custom routines). If not defined to math library routines + * (e.g., sqrt in libm.a), then the client is not forced to + * be linked with -lm. + */ + +#define XCMS_ATAN(x) _XcmsArcTangent(x) +#define XCMS_COS(x) _XcmsCosine(x) +#define XCMS_CUBEROOT(x) _XcmsCubeRoot(x) +#define XCMS_FABS(x) ((x) < 0.0 ? -(x) : (x)) +#define XCMS_SIN(x) _XcmsSine(x) +#define XCMS_SQRT(x) _XcmsSquareRoot(x) +#define XCMS_TAN(x) (XCMS_SIN(x) / XCMS_COS(x)) + +#ifdef __STDC__ +double _XcmsArcTangent(double a); +double _XcmsCosine(double a); +double _XcmsCubeRoot(double a); +double _XcmsSine(double a); +double _XcmsSquareRoot(double a); +#else +double _XcmsArcTangent(); +double _XcmsCosine(); +double _XcmsCubeRoot(); +double _XcmsSine(); +double _XcmsSquareRoot(); +#endif + +/* + * DEFINES FOR GAMUT COMPRESSION AND QUERY ROUTINES + */ +#ifndef PI +# ifdef M_PI +# define PI M_PI +# else +# define PI 3.14159265358979323846264338327950 +# endif /* M_PI */ +#endif /* PI */ +#ifndef degrees +# define degrees(r) ((XcmsFloat)(r) * 180.0 / PI) +#endif /* degrees */ +#ifndef radians +# define radians(d) ((XcmsFloat)(d) * PI / 180.0) +#endif /* radians */ + +#define XCMS_CIEUSTAROFHUE(h,c) \ +((XCMS_COS((h)) == 0.0) ? (XcmsFloat)0.0 : (XcmsFloat) \ +((XcmsFloat)(c) / (XcmsFloat)XCMS_SQRT((XCMS_TAN(h) * XCMS_TAN(h)) + \ +(XcmsFloat)1.0))) +#define XCMS_CIEVSTAROFHUE(h,c) \ +((XCMS_COS((h)) == 0.0) ? (XcmsFloat)0.0 : (XcmsFloat) \ +((XcmsFloat)(c) / (XcmsFloat)XCMS_SQRT(((XcmsFloat)1.0 / \ +(XcmsFloat)(XCMS_TAN(h) * XCMS_TAN(h))) + (XcmsFloat)1.0))) +/* this hue is returned in radians */ +#define XCMS_CIELUV_PMETRIC_HUE(u,v) \ +(((u) != 0.0) ? XCMS_ATAN( (v) / (u)) : ((v >= 0.0) ? PI / 2 : -(PI / 2))) +#define XCMS_CIELUV_PMETRIC_CHROMA(u,v) XCMS_SQRT(((u)*(u)) + ((v)*(v))) + +#define XCMS_CIEASTAROFHUE(h,c) XCMS_CIEUSTAROFHUE((h), (c)) +#define XCMS_CIEBSTAROFHUE(h,c) XCMS_CIEVSTAROFHUE((h), (c)) +#define XCMS_CIELAB_PMETRIC_HUE(a,b) XCMS_CIELUV_PMETRIC_HUE((a), (b)) +#define XCMS_CIELAB_PMETRIC_CHROMA(a,b) XCMS_CIELUV_PMETRIC_CHROMA((a), (b)) + +#endif /* _XCMSINT_H_ */ diff --git a/src/xcms/cmsAllCol.c b/src/xcms/cmsAllCol.c new file mode 100644 index 00000000..b631064b --- /dev/null +++ b/src/xcms/cmsAllCol.c @@ -0,0 +1,71 @@ +/* $Xorg: cmsAllCol.c,v 1.3 2000/08/17 19:45:08 cpqbld Exp $ */ + +/* + * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. + * All Rights Reserved + * + * This file is a component of an X Window System-specific implementation + * of Xcms based on the TekColor Color Management System. Permission is + * hereby granted to use, copy, modify, sell, and otherwise distribute this + * software and its documentation for any purpose and without fee, provided + * that this copyright, permission, and disclaimer notice is reproduced in + * all copies of this software and in supporting documentation. TekColor + * is a trademark of Tektronix, Inc. + * + * Tektronix makes no representation about the suitability of this software + * for any purpose. It is provided "as is" and with all faults. + * + * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, + * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX 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 THE PERFORMANCE OF THIS SOFTWARE. + * + * + * NAME + * XcmsAllCol.c + * + * DESCRIPTION + * Source for XcmsAllocColor + * + * + */ + +#include "Xlibint.h" +#include "Xcmsint.h" + + +/* + * NAME + * XcmsAllocColor - Allocate Color + * + * SYNOPSIS + */ +Status +XcmsAllocColor(dpy, colormap, pXcmsColor_in_out, result_format) + Display *dpy; + Colormap colormap; + XcmsColor *pXcmsColor_in_out; + XcmsColorFormat result_format; +/* + * DESCRIPTION + * Given a device-dependent or device-independent color + * specification, XcmsAllocColor will convert it to X RGB + * values then use it in a call to XAllocColor. + * + * RETURNS + * XcmsFailure if failed; + * XcmsSuccess if it succeeded without gamut compression; + * XcmsSuccessWithCompression if it succeeded with gamut + * compression; + * + * Also returns the pixel value of the color cell and a color + * specification of the color actually stored. + * + */ +{ + return(_XcmsSetGetColors (XAllocColor, dpy, colormap, pXcmsColor_in_out, 1, + result_format, (Bool *)NULL)); +} diff --git a/src/xcms/cmsAllNCol.c b/src/xcms/cmsAllNCol.c new file mode 100644 index 00000000..960173f8 --- /dev/null +++ b/src/xcms/cmsAllNCol.c @@ -0,0 +1,214 @@ +/* $Xorg: cmsAllNCol.c,v 1.3 2000/08/17 19:45:09 cpqbld Exp $ */ + +/* + * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. + * All Rights Reserved + * + * This file is a component of an X Window System-specific implementation + * of Xcms based on the TekColor Color Management System. Permission is + * hereby granted to use, copy, modify, sell, and otherwise distribute this + * software and its documentation for any purpose and without fee, provided + * that this copyright, permission, and disclaimer notice is reproduced in + * all copies of this software and in supporting documentation. TekColor + * is a trademark of Tektronix, Inc. + * + * Tektronix makes no representation about the suitability of this software + * for any purpose. It is provided "as is" and with all faults. + * + * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, + * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX 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 THE PERFORMANCE OF THIS SOFTWARE. + * + * + * NAME + * XcmsAlNCol.c + * + * DESCRIPTION + * Source for XcmsAllocNamedColor + * + * + */ + +#define NEED_REPLIES +#include <stdio.h> +#include "Xlibint.h" +#include "Xcmsint.h" + +/* + * EXTERNS + */ +extern void _XColor_to_XcmsRGB(); +extern void _XcmsRGB_to_XColor(); + + +/* + * NAME + * XcmsAllocNamedColor - + * + * SYNOPSIS + */ +#if NeedFunctionPrototypes +Status +XcmsAllocNamedColor ( + Display *dpy, + Colormap cmap, + _Xconst char *colorname, + XcmsColor *pColor_scrn_return, + XcmsColor *pColor_exact_return, + XcmsColorFormat result_format) +#else +Status +XcmsAllocNamedColor(dpy, cmap, colorname, pColor_scrn_return, + pColor_exact_return, result_format) + Display *dpy; + Colormap cmap; + char *colorname; + XcmsColor *pColor_scrn_return; + XcmsColor *pColor_exact_return; + XcmsColorFormat result_format; +#endif +/* + * DESCRIPTION + * Finds the color specification associated with the color + * name in the Device-Independent Color Name Database, then + * converts that color specification to an RGB format. This + * RGB value is then used in a call to XAllocColor to allocate + * a read-only color cell. + * + * RETURNS + * 0 if failed to parse string or find any entry in the database. + * 1 if succeeded in converting color name to XcmsColor. + * 2 if succeeded in converting color name to another color name. + * + */ +{ + long nbytes; + xAllocNamedColorReply rep; + xAllocNamedColorReq *req; + XColor hard_def; + XColor exact_def; + Status retval1 = 1; + Status retval2 = XcmsSuccess; + XcmsColor tmpColor; + XColor XColor_in_out; + XcmsCCC ccc; + + /* + * 0. Check for invalid arguments. + */ + if (dpy == NULL || colorname[0] == '\0' || pColor_scrn_return == 0 + || pColor_exact_return == NULL) { + return(XcmsFailure); + } + + if ((ccc = XcmsCCCOfColormap(dpy, cmap)) == (XcmsCCC)NULL) { + return(XcmsFailure); + } + + /* + * 1. Convert string to a XcmsColor using Xcms and i18n mechanism + */ + if ((retval1 = _XcmsResolveColorString(ccc, &colorname, + &tmpColor, result_format)) == XcmsFailure) { + return(XcmsFailure); + } + if (retval1 == _XCMS_NEWNAME) { + goto PassToServer; + } + memcpy((char *)pColor_exact_return, (char *)&tmpColor, sizeof(XcmsColor)); + + /* + * 2. Convert tmpColor to RGB + * Assume pColor_exact_return is now adjusted to Client White Point + */ + if ((retval2 = XcmsConvertColors(ccc, &tmpColor, + 1, XcmsRGBFormat, (Bool *) NULL)) == XcmsFailure) { + return(XcmsFailure); + } + + /* + * 3. Convert to XColor and call XAllocColor + */ + _XcmsRGB_to_XColor(&tmpColor, &XColor_in_out, 1); + if (XAllocColor(ccc->dpy, cmap, &XColor_in_out) == 0) { + return(XcmsFailure); + } + + /* + * 4. pColor_scrn_return + * + * Now convert to the target format. + * We can ignore the return value because we're already in a + * device-dependent format. + */ + _XColor_to_XcmsRGB(ccc, &XColor_in_out, pColor_scrn_return, 1); + if (result_format != XcmsRGBFormat) { + if (result_format == XcmsUndefinedFormat) { + result_format = pColor_exact_return->format; + } + if (XcmsConvertColors(ccc, pColor_scrn_return, 1, result_format, + (Bool *) NULL) == XcmsFailure) { + return(XcmsFailure); + } + } + + return(retval1 > retval2 ? retval1 : retval2); + +PassToServer: + /* + * All previous methods failed, so lets pass it to the server + * for parsing. + */ + dpy = ccc->dpy; + LockDisplay(dpy); + GetReq(AllocNamedColor, req); + + req->cmap = cmap; + nbytes = req->nbytes = strlen(colorname); + req->length += (nbytes + 3) >> 2; /* round up to mult of 4 */ + + _XSend(dpy, colorname, nbytes); + /* _XSend is more efficient that Data, since _XReply follows */ + + if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) { + UnlockDisplay(dpy); + SyncHandle(); + return (0); + } + + exact_def.red = rep.exactRed; + exact_def.green = rep.exactGreen; + exact_def.blue = rep.exactBlue; + + hard_def.red = rep.screenRed; + hard_def.green = rep.screenGreen; + hard_def.blue = rep.screenBlue; + + exact_def.pixel = hard_def.pixel = rep.pixel; + + UnlockDisplay(dpy); + SyncHandle(); + + /* + * Now convert to the target format. + */ + _XColor_to_XcmsRGB(ccc, &exact_def, pColor_exact_return, 1); + _XColor_to_XcmsRGB(ccc, &hard_def, pColor_scrn_return, 1); + if (result_format != XcmsRGBFormat + && result_format != XcmsUndefinedFormat) { + if (XcmsConvertColors(ccc, pColor_exact_return, 1, result_format, + (Bool *) NULL) == XcmsFailure) { + return(XcmsFailure); + } + if (XcmsConvertColors(ccc, pColor_scrn_return, 1, result_format, + (Bool *) NULL) == XcmsFailure) { + return(XcmsFailure); + } + } + + return(XcmsSuccess); +} diff --git a/src/xcms/cmsCmap.c b/src/xcms/cmsCmap.c new file mode 100644 index 00000000..84d60a46 --- /dev/null +++ b/src/xcms/cmsCmap.c @@ -0,0 +1,492 @@ +/* $Xorg: cmsCmap.c,v 1.3 2000/08/17 19:45:09 cpqbld Exp $ */ + +/* + * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. + * All Rights Reserved + * + * This file is a component of an X Window System-specific implementation + * of Xcms based on the TekColor Color Management System. Permission is + * hereby granted to use, copy, modify, sell, and otherwise distribute this + * software and its documentation for any purpose and without fee, provided + * that this copyright, permission, and disclaimer notice is reproduced in + * all copies of this software and in supporting documentation. TekColor + * is a trademark of Tektronix, Inc. + * + * Tektronix makes no representation about the suitability of this software + * for any purpose. It is provided "as is" and with all faults. + * + * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, + * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX 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 THE PERFORMANCE OF THIS SOFTWARE. + * + * + * NAME + * XcmsCmap.c - Client Colormap Management Routines + * + * DESCRIPTION + * Routines that store additional information about + * colormaps being used by the X Client. + * + * + */ + +#define NEED_EVENTS +#define NEED_REPLIES +#include "Xlibint.h" +#include "Xcmsint.h" +#include "Xutil.h" + +/* + * FORWARD DECLARATIONS + */ +XcmsCmapRec *_XcmsAddCmapRec(); +static void _XcmsFreeClientCmaps(); + + +/************************************************************************ + * * + * PRIVATE INTERFACES * + * * + ************************************************************************/ + +/* + * NAME + * CmapRecForColormap + * + * SYNOPSIS + */ +static XcmsCmapRec * +CmapRecForColormap(dpy, cmap) + Display *dpy; + Colormap cmap; +/* + * DESCRIPTION + * Find the corresponding XcmsCmapRec for cmap. In not found + * this routines attempts to create one. + * + * RETURNS + * Returns NULL if failed; otherwise the address to + * the corresponding XcmsCmapRec. + * + */ +{ + XcmsCmapRec *pRec; + int nScrn; + int i, j; + XVisualInfo visualTemplate; /* Template of the visual we want */ + XVisualInfo *visualList; /* List for visuals that match */ + int nVisualsMatched; /* Number of visuals that match */ + Window tmpWindow; + Visual *vp; + unsigned long border = 0; + _XAsyncHandler async; + _XAsyncErrorState async_state; + + for (pRec = (XcmsCmapRec *)dpy->cms.clientCmaps; pRec != NULL; + pRec = pRec->pNext) { + if (pRec->cmapID == cmap) { + return(pRec); + } + } + + /* + * Can't find an XcmsCmapRec associated with cmap in our records. + * Let's try to see if its a default colormap + */ + nScrn = ScreenCount(dpy); + for (i = 0; i < nScrn; i++) { + if (cmap == DefaultColormap(dpy, i)) { + /* It is ... lets go ahead and store that info */ + if ((pRec = _XcmsAddCmapRec(dpy, cmap, RootWindow(dpy, i), + DefaultVisual(dpy, i))) == NULL) { + return((XcmsCmapRec *)NULL); + } + pRec->ccc = XcmsCreateCCC( + dpy, + i, /* screenNumber */ + DefaultVisual(dpy, i), + (XcmsColor *)NULL, /* clientWhitePt */ + (XcmsCompressionProc)NULL, /* gamutCompProc */ + (XPointer)NULL, /* gamutCompClientData */ + (XcmsWhiteAdjustProc)NULL, /* whitePtAdjProc */ + (XPointer)NULL /* whitePtAdjClientData */ + ); + return(pRec); + } + } + + /* + * Nope, its not a default colormap, so it's probably a foreign color map + * of which we have no specific details. Let's go through the + * rigorous process of finding this colormap: + * for each screen + * for each screen's visual types + * create a window with cmap specified as the colormap + * if successful + * Add a CmapRec + * Create an XcmsCCC + * return the CmapRec + * else + * continue + */ + + async_state.error_code = 0; /* don't care */ + async_state.major_opcode = X_CreateWindow; + async_state.minor_opcode = 0; + for (i = 0; i < nScrn; i++) { + visualTemplate.screen = i; + visualList = XGetVisualInfo(dpy, VisualScreenMask, &visualTemplate, + &nVisualsMatched); + if (nVisualsMatched == 0) { + continue; + } + + /* + * Attempt to create a window with cmap + */ + j = 0; + do { + vp = (visualList+j)->visual; + LockDisplay(dpy); + { + register xCreateWindowReq *req; + + GetReq(CreateWindow, req); + async_state.min_sequence_number = dpy->request; + async_state.max_sequence_number = dpy->request; + async_state.error_count = 0; + async.next = dpy->async_handlers; + async.handler = _XAsyncErrorHandler; + async.data = (XPointer)&async_state; + dpy->async_handlers = &async; + req->parent = RootWindow(dpy, i); + req->x = 0; + req->y = 0; + req->width = 1; + req->height = 1; + req->borderWidth = 0; + req->depth = (visualList+j)->depth; + req->class = CopyFromParent; + req->visual = vp->visualid; + tmpWindow = req->wid = XAllocID(dpy); + req->mask = CWBorderPixel | CWColormap; + req->length += 2; + Data32 (dpy, (long *) &border, 4); + Data32 (dpy, (long *) &cmap, 4); + } + { + xGetInputFocusReply rep; + register xReq *req; + + GetEmptyReq(GetInputFocus, req); + (void) _XReply (dpy, (xReply *)&rep, 0, xTrue); + } + DeqAsyncHandler(dpy, &async); + UnlockDisplay(dpy); + SyncHandle(); + } while (async_state.error_count > 0 && ++j < nVisualsMatched); + + Xfree((char *)visualList); + + /* + * if successful + */ + if (j < nVisualsMatched) { + if ((pRec = _XcmsAddCmapRec(dpy, cmap, tmpWindow, vp)) == NULL) + return((XcmsCmapRec *)NULL); + pRec->ccc = XcmsCreateCCC( + dpy, + i, /* screenNumber */ + vp, + (XcmsColor *)NULL, /* clientWhitePt */ + (XcmsCompressionProc)NULL, /* gamutCompProc */ + (XPointer)NULL, /* gamutCompClientData */ + (XcmsWhiteAdjustProc)NULL, /* whitePtAdjProc */ + (XPointer)NULL /* whitePtAdjClientData */ + ); + XDestroyWindow(dpy, tmpWindow); + return(pRec); + } + } + + return(NULL); +} + + + +/************************************************************************ + * * + * API PRIVATE INTERFACES * + * * + ************************************************************************/ + +/* + * NAME + * _XcmsAddCmapRec + * + * SYNOPSIS + */ +XcmsCmapRec * +_XcmsAddCmapRec(dpy, cmap, windowID, visual) + Display *dpy; + Colormap cmap; + Window windowID; + Visual *visual; +/* + * DESCRIPTION + * Create an XcmsCmapRec for the specified cmap, windowID, + * and visual, then adds it to its list of CmapRec's. + * + * RETURNS + * Returns NULL if failed; otherwise the address to + * the added XcmsCmapRec. + * + */ +{ + XcmsCmapRec *pNew; + + if ((pNew = (XcmsCmapRec *) Xcalloc(1, (unsigned) sizeof(XcmsCmapRec))) + == NULL) { + return((XcmsCmapRec *)NULL); + } + + pNew->cmapID = cmap; + pNew->dpy = dpy; + pNew->windowID = windowID; + pNew->visual = visual; + pNew->pNext = (XcmsCmapRec *)dpy->cms.clientCmaps; + dpy->cms.clientCmaps = (XPointer)pNew; + dpy->free_funcs->clientCmaps = _XcmsFreeClientCmaps; + + /* + * Note, we don't create the XcmsCCC for pNew->ccc here because + * it may require the use of XGetWindowAttributes (a round trip request) + * to determine the screen. + */ + return(pNew); +} + + +/* + * NAME + * _XcmsCopyCmapRecAndFree + * + * SYNOPSIS + */ +XcmsCmapRec * +_XcmsCopyCmapRecAndFree(dpy, src_cmap, copy_cmap) + Display *dpy; + Colormap src_cmap; + Colormap copy_cmap; +/* + * DESCRIPTION + * Augments Xlib's XCopyColormapAndFree() to copy + * XcmsCmapRecs. + * + * RETURNS + * Returns NULL if failed; otherwise the address to + * the copy XcmsCmapRec. + * + */ +{ + XcmsCmapRec *pRec_src; + XcmsCmapRec *pRec_copy; + + if ((pRec_src = CmapRecForColormap(dpy, src_cmap)) != NULL) { + pRec_copy =_XcmsAddCmapRec(dpy, copy_cmap, pRec_src->windowID, + pRec_src->visual); + if (pRec_copy != NULL && pRec_src->ccc) { + pRec_copy->ccc = (XcmsCCC)Xcalloc(1, (unsigned) sizeof(XcmsCCCRec)); + memcpy((char *)pRec_copy->ccc, (char *)pRec_src->ccc, + sizeof(XcmsCCCRec)); + } + return(pRec_copy); + } + return((XcmsCmapRec *)NULL); +} + + +/* + * NAME + * _XcmsDeleteCmapRec + * + * SYNOPSIS + */ +void +_XcmsDeleteCmapRec(dpy, cmap) + Display *dpy; + Colormap cmap; +/* + * DESCRIPTION + * Removes and frees the specified XcmsCmapRec structure + * from the linked list of structures. + * + * RETURNS + * void + * + */ +{ + XcmsCmapRec **pPrevPtr; + XcmsCmapRec *pRec; + int scr; + + /* If it is the default cmap for a screen, do not delete it, + * because the server will not actually free it */ + for (scr = ScreenCount(dpy); --scr >= 0; ) { + if (cmap == DefaultColormap(dpy, scr)) + return; + } + + /* search for it in the list */ + pPrevPtr = (XcmsCmapRec **)&dpy->cms.clientCmaps; + while ((pRec = *pPrevPtr) && (pRec->cmapID != cmap)) { + pPrevPtr = &pRec->pNext; + } + + if (pRec) { + if (pRec->ccc) { + XcmsFreeCCC(pRec->ccc); + } + *pPrevPtr = pRec->pNext; + Xfree((char *)pRec); + } +} + + +/* + * NAME + * _XcmsFreeClientCmaps + * + * SYNOPSIS + */ +static void +_XcmsFreeClientCmaps(dpy) + Display *dpy; +/* + * DESCRIPTION + * Frees all XcmsCmapRec structures in the linked list + * and sets dpy->cms.clientCmaps to NULL. + * + * RETURNS + * void + * + */ +{ + XcmsCmapRec *pRecNext, *pRecFree; + + pRecNext = (XcmsCmapRec *)dpy->cms.clientCmaps; + while (pRecNext != NULL) { + pRecFree = pRecNext; + pRecNext = pRecNext->pNext; + if (pRecFree->ccc) { + /* Free the XcmsCCC structure */ + XcmsFreeCCC(pRecFree->ccc); + } + /* Now free the XcmsCmapRec structure */ + Xfree((char *)pRecFree); + } + dpy->cms.clientCmaps = (XPointer)NULL; +} + + + +/************************************************************************ + * * + * PUBLIC INTERFACES * + * * + ************************************************************************/ + +/* + * NAME + * XcmsCCCOfColormap + * + * SYNOPSIS + */ +XcmsCCC +XcmsCCCOfColormap(dpy, cmap) + Display *dpy; + Colormap cmap; +/* + * DESCRIPTION + * Finds the XcmsCCC associated with the specified colormap. + * + * RETURNS + * Returns NULL if failed; otherwise the address to + * the associated XcmsCCC structure. + * + */ +{ + XWindowAttributes windowAttr; + XcmsCmapRec *pRec; + int nScrn = ScreenCount(dpy); + int i; + + if ((pRec = CmapRecForColormap(dpy, cmap)) != NULL) { + if (pRec->ccc) { + /* XcmsCmapRec already has a XcmsCCC */ + return(pRec->ccc); + } + + /* + * The XcmsCmapRec does not have a XcmsCCC yet, so let's create + * one. But first, we need to know the screen associated with + * cmap, so use XGetWindowAttributes() to extract that + * information. Unless, of course there is only one screen!! + */ + if (nScrn == 1) { + /* Assume screenNumber == 0 */ + return(pRec->ccc = XcmsCreateCCC( + dpy, + 0, /* screenNumber */ + pRec->visual, + (XcmsColor *)NULL, /* clientWhitePt */ + (XcmsCompressionProc)NULL, /* gamutCompProc */ + (XPointer)NULL, /* gamutCompClientData */ + (XcmsWhiteAdjustProc)NULL, /* whitePtAdjProc */ + (XPointer)NULL /* whitePtAdjClientData */ + )); + } else { + if (XGetWindowAttributes(dpy, pRec->windowID, &windowAttr)) { + for (i = 0; i < nScrn; i++) { + if (ScreenOfDisplay(dpy, i) == windowAttr.screen) { + return(pRec->ccc = XcmsCreateCCC( + dpy, + i, /* screenNumber */ + pRec->visual, + (XcmsColor *)NULL, /* clientWhitePt */ + (XcmsCompressionProc)NULL, /* gamutCompProc */ + (XPointer)NULL, /* gamutCompClientData */ + (XcmsWhiteAdjustProc)NULL, /* whitePtAdjProc */ + (XPointer)NULL /* whitePtAdjClientData */ + )); + } + } + } + } + } + + /* + * No such cmap + */ + return(NULL); +} + +XcmsCCC XcmsSetCCCOfColormap(dpy, cmap, ccc) + Display *dpy; + Colormap cmap; + XcmsCCC ccc; +{ + XcmsCCC prev_ccc = NULL; + XcmsCmapRec *pRec; + + pRec = CmapRecForColormap(dpy, cmap); + if (pRec) { + prev_ccc = pRec->ccc; + pRec->ccc = ccc; + } + return prev_ccc; +} diff --git a/src/xcms/cmsColNm.c b/src/xcms/cmsColNm.c new file mode 100644 index 00000000..e4a9fc90 --- /dev/null +++ b/src/xcms/cmsColNm.c @@ -0,0 +1,1049 @@ +/* $Xorg: cmsColNm.c,v 1.3 2000/08/17 19:45:09 cpqbld Exp $ */ + +/* + * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. + * All Rights Reserved + * + * This file is a component of an X Window System-specific implementation + * of Xcms based on the TekColor Color Management System. Permission is + * hereby granted to use, copy, modify, sell, and otherwise distribute this + * software and its documentation for any purpose and without fee, provided + * that this copyright, permission, and disclaimer notice is reproduced in + * all copies of this software and in supporting documentation. TekColor + * is a trademark of Tektronix, Inc. + * + * Tektronix makes no representation about the suitability of this software + * for any purpose. It is provided "as is" and with all faults. + * + * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, + * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX 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 THE PERFORMANCE OF THIS SOFTWARE. + * + * NAME + * XcmsColNm.c + * + * DESCRIPTION + * Source for _XcmsLookupColorName(). + * + * + */ + +#include "Xlibint.h" +#include "Xcmsint.h" +#include <X11/Xos.h> +#include <sys/stat.h> +#include <stdio.h> +#include <ctype.h> +#define XK_LATIN1 +#include <X11/keysymdef.h> + + +/* + * EXTERNS + * External declarations required locally to this package + * that are not already declared in any of the included header + * files (external includes or internal includes). + */ +#ifdef X_NOT_STDC_ENV +extern char *getenv(); +extern void qsort(); +extern char *bsearch(); +#endif +extern XcmsColorSpace **_XcmsDIColorSpaces; +static Status LoadColornameDB(); +void _XcmsCopyISOLatin1Lowered(); + +/* + * LOCAL DEFINES + * #define declarations local to this package. + */ +#ifndef XCMSDB +#define XCMSDB "/usr/lib/X11/Xcms.txt" +#endif + +#ifndef isgraph +# define isgraph(c) (isprint((c)) && !isspace((c))) +#endif + +#ifndef XCMSDB_MAXLINELEN +# define XCMSDB_MAXLINELEN 256 +#endif + +#define FORMAT_VERSION "0.1" +#define START_TOKEN "XCMS_COLORDB_START" +#define END_TOKEN "XCMS_COLORDB_END" +#define DELIM_CHAR '\t' + +#define NOT_VISITED 0x0 +#define VISITED 0x1 +#define CYCLE 0xFFFF +#define XcmsDbInitNone -1 +#define XcmsDbInitFailure 0 +#define XcmsDbInitSuccess 1 + +/* + * LOCAL TYPEDEFS + */ +typedef struct _XcmsPair { + char *first; + char *second; + int flag; +} XcmsPair; + +/* + * LOCAL VARIABLES + */ +static int XcmsColorDbState = XcmsDbInitNone; +static int nEntries; +static char *strings; +static XcmsPair *pairs; +static char whitePtStr[] = "WhitePoint"; + + +/************************************************************************ + * * + * PRIVATE ROUTINES * + * * + ************************************************************************/ + +/* + * NAME + * _XcmsColorSpaceOfString + * + * SYNOPSIS + */ +static XcmsColorSpace * +_XcmsColorSpaceOfString(ccc, color_string) + XcmsCCC ccc; + char *color_string; +/* + * DESCRIPTION + * Returns a pointer to the color space structure + * (XcmsColorSpace) associated with the specified color string. + * + * RETURNS + * Pointer to matching XcmsColorSpace structure if found; + * otherwise NULL. + * + * CAVEATS + * + */ +{ + XcmsColorSpace **papColorSpaces; + int n; + char *pchar; + + if ((pchar = strchr(color_string, ':')) == NULL) { + return(XcmsFailure); + } + n = (int)(pchar - color_string); + + if (ccc == NULL) { + return(NULL); + } + + /* + * First try Device-Independent color spaces + */ + papColorSpaces = _XcmsDIColorSpaces; + if (papColorSpaces != NULL) { + while (*papColorSpaces != NULL) { + if (strncmp((*papColorSpaces)->prefix, color_string, n) == 0 && + !((*papColorSpaces)->prefix)[n]) { + return(*papColorSpaces); + } + papColorSpaces++; + } + } + + /* + * Next try Device-Dependent color spaces + */ + papColorSpaces = ((XcmsFunctionSet *)ccc->pPerScrnInfo->functionSet)->DDColorSpaces; + if (papColorSpaces != NULL) { + while (*papColorSpaces != NULL) { + if (strncmp((*papColorSpaces)->prefix, color_string, n) == 0 && + !((*papColorSpaces)->prefix)[n]) { + return(*papColorSpaces); + } + papColorSpaces++; + } + } + + return(NULL); +} + + +/* + * NAME + * _XcmsParseColorString + * + * SYNOPSIS + */ +static int +_XcmsParseColorString(ccc, color_string, pColor) + XcmsCCC ccc; + char *color_string; + XcmsColor *pColor; +/* + * DESCRIPTION + * Assuming color_string contains a numerical string color + * specification, attempts to parse a string into an + * XcmsColor structure. + * + * RETURNS + * 0 if failed; otherwise non-zero. + * + * CAVEATS + * A color string containing a numerical color specification + * must be in ISO Latin-1 encoding! + */ +{ + XcmsColorSpace *pColorSpace; + char string_buf[64]; + char *string_lowered; + int len; + int res; + + if (ccc == NULL) { + return(0); + } + + /* + * While copying color_string to string_lowered, convert to lowercase + */ + if ((len = strlen(color_string)) >= sizeof(string_buf)) { + string_lowered = (char *) Xmalloc(len+1); + } else { + string_lowered = string_buf; + } + + _XcmsCopyISOLatin1Lowered(string_lowered, color_string); + + if (*string_lowered == '#') { + if ((pColorSpace = _XcmsColorSpaceOfString(ccc, "rgb:")) != NULL) { + res = (*pColorSpace->parseString)(string_lowered, pColor); + if (len >= sizeof(string_buf)) Xfree(string_lowered); + return res; + } + } + + if ((pColorSpace = _XcmsColorSpaceOfString(ccc, string_lowered)) != NULL) { + res = (*pColorSpace->parseString)(string_lowered, pColor); + if (len >= sizeof(string_buf)) Xfree(string_lowered); + return res; + } + + if (len >= sizeof(string_buf)) Xfree(string_lowered); + return(0); +} + + +/* + * NAME + * FirstCmp - Compare color names of pair recs + * + * SYNOPSIS + */ +static int +FirstCmp(p1, p2) +#ifdef __STDC__ + const void *p1, *p2; +#else + XcmsPair *p1, *p2; +#endif +/* + * DESCRIPTION + * Compares the color names of XcmsColorTuples. + * This routine is public to allow access from qsort???. + * + * RETURNS + * 0 if equal; + * < 0 if first precedes second, + * > 0 if first succeeds second. + * + */ +{ + return(strcmp(((XcmsPair *)p1)->first, ((XcmsPair *)p2)->first)); +} + + + +/* + * NAME + * stringSectionSize - determine memory needed for strings + * + * SYNOPSIS + */ +static void +SetNoVisit() +/* + * DESCRIPTION + * + * RETURNS + * void + * + */ +{ + int i; + XcmsPair *pair = pairs; + + for (i = 0; i < nEntries; i++, pair++) { + if (pair->flag != CYCLE) { + pair->flag = NOT_VISITED; + } + } +} + + + + +/* + * NAME + * field2 - extract two fields + * + * SYNOPSIS + */ +static int +field2(pBuf, delim, p1, p2) + char *pBuf; + char delim; /* in: field delimiter */ + char **p1; /* in/out: pointer to pointer to field 1 */ + char **p2; /* in/out: pointer to pointer to field 2 */ +/* + * DESCRIPTION + * Extracts two fields from a "record". + * + * RETURNS + * XcmsSuccess if succeeded, otherwise XcmsFailure. + * + */ +{ + *p1 = *p2 = NULL; + + /* Find Field 1 */ + while (!isgraph(*pBuf)) { + if ((*pBuf != '\n') || (*pBuf != '\0')) { + return(XcmsFailure); + } + if (isspace(*pBuf) || (*pBuf == delim)) { + pBuf++; + } + } + *p1 = pBuf; + + /* Find end of Field 2 */ + while (isprint(*pBuf) && (*pBuf != delim)) { + pBuf++; + } + if ((*pBuf == '\n') || (*pBuf == '\0')) { + return(XcmsFailure); + } + if ((*pBuf == ' ') || (*pBuf == delim)) { + *pBuf++ = '\0'; /* stuff end of string character */ + } else { + return(XcmsFailure); + } + + /* Find Field 2 */ + while (!isgraph(*pBuf)) { + if ((*pBuf == '\n') || (*pBuf == '\0')) { + return(XcmsFailure); + } + if (isspace(*pBuf) || (*pBuf == delim)) { + pBuf++; + } + } + *p2 = pBuf; + + /* Find end of Field 2 */ + while (isprint(*pBuf) && (*pBuf != delim)) { + pBuf++; + } + if (*pBuf != '\0') { + *pBuf = '\0'; /* stuff end of string character */ + } + + return(XcmsSuccess); +} + + +/* + * NAME + * _XcmsLookupColorName - Lookup DB entry for a color name + * + * SYNOPSIS + */ +static Status +_XcmsLookupColorName(ccc, name, pColor) + XcmsCCC ccc; + char **name; + XcmsColor *pColor; +/* + * DESCRIPTION + * Searches for an entry in the Device-Independent Color Name + * Database for the specified string. + * + * RETURNS + * XcmsFailure if failed to find a matching entry in + * the database. + * XcmsSuccess if succeeded in converting color name to + * XcmsColor. + * _XCMS_NEWNAME if succeeded in converting color string (which + * is a color name to yet another color name. Note + * that the new name is passed back via 'name'. + */ + { + Status retval = 0; + char name_lowered_64[64]; + char *name_lowered; + register int i, j, left, right; + int len; + char *tmpName; + XcmsPair *pair; + + /* + * Check state of Database: + * XcmsDbInitNone + * XcmsDbInitSuccess + * XcmsDbInitFailure + */ + if (XcmsColorDbState == XcmsDbInitFailure) { + return(XcmsFailure); + } + if (XcmsColorDbState == XcmsDbInitNone) { + if (!LoadColornameDB()) { + return(XcmsFailure); + } + } + + SetNoVisit(); + + /* + * While copying name to name_lowered, convert to lowercase + */ + + tmpName = *name; + +Retry: + if ((len = strlen(tmpName)) > 63) { + name_lowered = (char *) Xmalloc(len+1); + } else { + name_lowered = name_lowered_64; + } + + _XcmsCopyISOLatin1Lowered(name_lowered, tmpName); + + /* + * Now, remove spaces. + */ + for (i = 0, j = 0; j < len; j++) { + if (!isspace(name_lowered[j])) { + name_lowered[i++] = name_lowered[j]; + } + } + name_lowered[i] = '\0'; + + left = 0; + right = nEntries - 1; + while (left <= right) { + i = (left + right) >> 1; + pair = &pairs[i]; + j = strcmp(name_lowered, pair->first); + if (j < 0) + right = i - 1; + else if (j > 0) + left = i + 1; + else { + break; + } + } + if (len > 63) Xfree(name_lowered); + + if (left > right) { + if (retval == 2) { + if (*name != tmpName) { + *name = tmpName; + } + return(_XCMS_NEWNAME); + } + return(XcmsFailure); + } + + if (pair->flag == CYCLE) { + return(XcmsFailure); + } + if (pair->flag == VISITED) { + pair->flag = CYCLE; + return(XcmsFailure); + } + + if (_XcmsParseColorString(ccc, pair->second, pColor) == XcmsSuccess) { + /* f2 contains a numerical string specification */ + return(XcmsSuccess); + } else { + /* f2 does not contain a numerical string specification */ + tmpName = pair->second; + pair->flag = VISITED; + retval = 2; + goto Retry; + } +} + + +/* + * NAME + * RemoveSpaces + * + * SYNOPSIS + */ +static int +RemoveSpaces(pString) + char *pString; +/* + * DESCRIPTION + * Removes spaces from string. + * + * RETURNS + * Void + * + */ +{ + int i, count = 0; + char *cptr; + + /* REMOVE SPACES */ + cptr = pString; + for (i = strlen(pString); i; i--, cptr++) { + if (!isspace(*cptr)) { + *pString++ = *cptr; + count++; + } + } + *pString = '\0'; + return(count); +} + + +/* + * NAME + * stringSectionSize - determine memory needed for strings + * + * SYNOPSIS + */ +static int +stringSectionSize(stream, pNumEntries, pSectionSize) + FILE *stream; + int *pNumEntries; + int *pSectionSize; +/* + * DESCRIPTION + * Determines the amount of memory required to store the + * color name strings and also the number of strings. + * + * RETURNS + * XcmsSuccess if succeeded, otherwise XcmsFailure. + * + */ +{ + char buf[XCMSDB_MAXLINELEN]; + char token[XCMSDB_MAXLINELEN]; + char token2[XCMSDB_MAXLINELEN]; + char *pBuf; + char *f1; + char *f2; + int i; + + *pNumEntries = 0; + *pSectionSize = 0; + + /* + * Advance to START_TOKEN + * Anything before is just considered as comments. + */ + + while((pBuf = fgets(buf, XCMSDB_MAXLINELEN, stream)) != NULL) { + if ((sscanf(buf, "%s %s", token, token2)) + && (strcmp(token, START_TOKEN) == 0)) { + if (strcmp(token2, FORMAT_VERSION) != 0) { + /* text file not in the right format */ + return(XcmsFailure); + } + break; + } /* else it was just a blank line or comment */ + } + + if (pBuf == NULL) { + return(XcmsFailure); + } + + while((pBuf = fgets(buf, XCMSDB_MAXLINELEN, stream)) != NULL) { + if ((sscanf(buf, "%s", token)) && (strcmp(token, END_TOKEN) == 0)) { + break; + } + + if (field2(buf, DELIM_CHAR, &f1, &f2) != XcmsSuccess) { + return(XcmsFailure); + } + + (*pNumEntries)++; + + (*pSectionSize) += (i = strlen(f1)) + 1; + for (; i; i--, f1++) { + /* REMOVE SPACES FROM COUNT */ + if (isspace(*f1)) { + (*pSectionSize)--; + } + } + + (*pSectionSize) += (i = strlen(f2)) + 1; + for (; i; i--, f2++) { + /* REMOVE SPACES FROM COUNT */ + if (isspace(*f2)) { + (*pSectionSize)--; + } + } + + } + + return(XcmsSuccess); +} + + +/* + * NAME + * ReadColornameDB - Read the Color Name Database + * + * SYNOPSIS + */ +static Status +ReadColornameDB(stream, pRec, pString) + FILE *stream; + XcmsPair *pRec; + char *pString; +/* + * DESCRIPTION + * Loads the Color Name Database from a text file. + * + * RETURNS + * XcmsSuccess if succeeded, otherwise XcmsFailure. + * + */ +{ + char buf[XCMSDB_MAXLINELEN]; + char token[XCMSDB_MAXLINELEN]; + char token2[XCMSDB_MAXLINELEN]; + char *f1; + char *f2; + char *pBuf; + + /* + * Advance to START_TOKEN + * Anything before is just considered as comments. + */ + + while((pBuf = fgets(buf, XCMSDB_MAXLINELEN, stream)) != NULL) { + if ((sscanf(buf, "%s %s", token, token2)) + && (strcmp(token, START_TOKEN) == 0)) { + if (strcmp(token2, FORMAT_VERSION) != 0) { + /* text file not in the right format */ + return(XcmsFailure); + } + break; + } /* else it was just a blank line or comment */ + } + + if (pBuf == NULL) { + return(XcmsFailure); + } + + /* + * Process lines between START_TOKEN to END_TOKEN + */ + + while ((pBuf = fgets(buf, XCMSDB_MAXLINELEN, stream)) != NULL) { + if ((sscanf(buf, "%s", token)) && (strcmp(token, END_TOKEN) == 0)) { + /* + * Found END_TOKEN so break out of for loop + */ + break; + } + + /* + * Get pairs + */ + if (field2(buf, DELIM_CHAR, &f1, &f2) != XcmsSuccess) { + /* Invalid line */ + continue; + } + + /* + * Add strings + */ + + /* Left String */ + pRec->first = pString; + _XcmsCopyISOLatin1Lowered(pString, f1); + pString += (1 + RemoveSpaces(pString)); + pRec->second = pString; + /* Right String */ + _XcmsCopyISOLatin1Lowered(pString, f2); + pString += RemoveSpaces(pString) + 1; + pRec++; + + } + + return(XcmsSuccess); +} + + +/* + * NAME + * LoadColornameDB - Load the Color Name Database + * + * SYNOPSIS + */ +static Status +LoadColornameDB() +/* + * DESCRIPTION + * Loads the Color Name Database from a text file. + * + * RETURNS + * XcmsSuccess if succeeded, otherwise XcmsFailure. + * + */ +{ + int size; + FILE *stream; + char *pathname; + struct stat txt; + int length; + + /* use and name of this env var is not part of the standard */ + /* implementation-dependent feature */ + if ((pathname = getenv("XCMSDB")) == NULL) { + pathname = XCMSDB; + } + + length = strlen(pathname); + if ((length == 0) || (length >= (BUFSIZ - 5))){ + XcmsColorDbState = XcmsDbInitFailure; + return(XcmsFailure); + } + + if (stat(pathname, &txt)) { + /* can't stat file */ + XcmsColorDbState = XcmsDbInitFailure; + return(XcmsFailure); + } + + if ((stream = _XFopenFile (pathname, "r")) == NULL) { + return(XcmsFailure); + } + + stringSectionSize(stream, &nEntries, &size); + rewind(stream); + + strings = (char *) Xmalloc(size); + pairs = (XcmsPair *)Xcalloc(nEntries, sizeof(XcmsPair)); + + ReadColornameDB(stream, pairs, strings); + (void) fclose(stream); + + /* + * sort the pair recs + */ + qsort((char *)pairs, nEntries, sizeof(XcmsPair), FirstCmp); + + XcmsColorDbState = XcmsDbInitSuccess; + return(XcmsSuccess); +} + + +/************************************************************************ + * * + * API PRIVATE ROUTINES * + * * + ************************************************************************/ + +/* + * NAME + * _XcmsCopyISOLatin1Lowered + * + * SYNOPSIS + */ +void +_XcmsCopyISOLatin1Lowered(dst, src) + char *dst, *src; +/* + * DESCRIPTION + * ISO Latin-1 case conversion routine + * Identical to XmuCopyISOLatin1Lowered() but provided here + * to eliminate need to link with libXmu.a. + * + * IMPLEMENTORS NOTE: + * This routine is also used in XcmsFormatOfPrefix. + * + * RETURNS + * Void + * + */ +{ + register unsigned char *dest, *source; + + for (dest = (unsigned char *)dst, source = (unsigned char *)src; + *source; + source++, dest++) + { + if ((*source >= XK_A) && (*source <= XK_Z)) + *dest = *source + (XK_a - XK_A); + else if ((*source >= XK_Agrave) && (*source <= XK_Odiaeresis)) + *dest = *source + (XK_agrave - XK_Agrave); + else if ((*source >= XK_Ooblique) && (*source <= XK_Thorn)) + *dest = *source + (XK_oslash - XK_Ooblique); + else + *dest = *source; + } + *dest = '\0'; +} + + +/* + * NAME + * _XcmsResolveColorString - + * + * SYNOPSIS + */ +#if NeedFunctionPrototypes +Status +_XcmsResolveColorString ( + XcmsCCC ccc, + _Xconst char **color_string, + XcmsColor *pColor_exact_return, + XcmsColorFormat result_format) +#else +Status +_XcmsResolveColorString(ccc, color_string, pColor_exact_return, result_format) + XcmsCCC ccc; + char **color_string; + XcmsColor *pColor_exact_return; + XcmsColorFormat result_format; +#endif +/* + * DESCRIPTION + * The XcmsLookupColor function finds the color specification + * associated with a color name in the Device-Independent Color + * Name Database. + * RETURNS + * XcmsFailure if failed to convert valid color string. + * XcmsSuccess if succeeded in converting color string to + * XcmsColor. + * _XCMS_NEWNAME if failed to parse the string or find it in + * the database, or if succeeded in looking it up and + * found another name which is not in the database. + * Note that the new name is returned in color_string. + * + * This function returns both the color specification found in the + * database (db specification) and the color specification for the + * color displayable by the specified screen (screen + * specification). The calling routine sets the format for these + * returned specifications in the XcmsColor format component. + * If XcmsUndefinedFormat, the specification is returned in the + * format used to store the color in the database. + */ +{ + XcmsColor dbWhitePt; /* whitePt associated with pColor_exact_return*/ + /* the screen's white point */ + XcmsColor *pClientWhitePt; + int retval; + char *strptr = whitePtStr; + +/* + * 0. Check for invalid arguments. + */ + if (ccc == NULL || (*color_string)[0] == '\0' || pColor_exact_return == NULL) { + return(XcmsFailure); + } + +/* + * 1. First attempt to parse the string + * If successful, then convert the specification to the target format + * and return. + */ + if (_XcmsParseColorString(ccc, *color_string, pColor_exact_return) + == 1) { + if (result_format != XcmsUndefinedFormat + && pColor_exact_return->format != result_format) { + /* need to be converted to the target format */ + return(XcmsConvertColors(ccc, pColor_exact_return, 1, + result_format, (Bool *)NULL)); + } else { + return(XcmsSuccess); + } + } + +/* + * 2. Attempt to find it in the DI Color Name Database + */ + + /* + * a. Convert String into a XcmsColor structure + * Attempt to extract the specification for color_string from the + * DI Database (pColor_exact_return). If the DI Database does not + * have this entry, then return failure. + */ + retval = _XcmsLookupColorName(ccc, color_string, pColor_exact_return); + + if (retval != XcmsSuccess) { + /* color_string replaced with a color name, or not found */ + return(_XCMS_NEWNAME); + } + + if (pColor_exact_return->format == XcmsUndefinedFormat) { + return(XcmsFailure); + } + + /* + * b. If result_format not defined, then assume target format + * is the exact format. + */ + if (result_format == XcmsUndefinedFormat) { + result_format = pColor_exact_return->format; + } + + if ((ClientWhitePointOfCCC(ccc))->format == XcmsUndefinedFormat) { + pClientWhitePt = ScreenWhitePointOfCCC(ccc); + } else { + pClientWhitePt = ClientWhitePointOfCCC(ccc); + } + + /* + * c. Convert to the target format, making adjustments for white + * point differences as necessary. + */ + if (XCMS_DD_ID(pColor_exact_return->format)) { + /* + * The spec format is Device-Dependent, therefore assume the + * its white point is the Screen White Point. + */ + if (XCMS_DD_ID(result_format)) { + /* + * Target format is Device-Dependent + * Therefore, DD --> DD conversion + */ + return(_XcmsDDConvertColors(ccc, pColor_exact_return, + 1, result_format, (Bool *) NULL)); + } else { + /* + * Target format is Device-Independent + * Therefore, DD --> DI conversion + */ + if (ccc->whitePtAdjProc && !_XcmsEqualWhitePts(ccc, + pClientWhitePt, ScreenWhitePointOfCCC(ccc))) { + return((*ccc->whitePtAdjProc)(ccc, ScreenWhitePointOfCCC(ccc), + pClientWhitePt, result_format, + pColor_exact_return, 1, (Bool *) NULL)); + } else { + if (_XcmsDDConvertColors(ccc, pColor_exact_return, 1, + XcmsCIEXYZFormat, (Bool *) NULL) == XcmsFailure) { + return(XcmsFailure); + } + return(_XcmsDIConvertColors(ccc, pColor_exact_return, + pClientWhitePt, 1, result_format)); + } + } + } else { + /* + * The spec format is Device-Independent, therefore attempt + * to find a database white point. + * + * If the Database does not have a white point, then assume the + * database white point is the same as the Screen White Point. + */ + + if (_XcmsLookupColorName(ccc, &strptr, &dbWhitePt) != 1) { + memcpy((char *)&dbWhitePt, + (char *)&ccc->pPerScrnInfo->screenWhitePt, + sizeof(XcmsColor)); + } + if (XCMS_DD_ID(result_format)) { + /* + * Target format is Device-Dependent + * Therefore, DI --> DD conversion + */ + if (ccc->whitePtAdjProc && !_XcmsEqualWhitePts(ccc, + &dbWhitePt, ScreenWhitePointOfCCC(ccc))) { + return((*ccc->whitePtAdjProc)(ccc, &dbWhitePt, + ScreenWhitePointOfCCC(ccc), result_format, + pColor_exact_return, 1, (Bool *)NULL)); + } else { + if (pColor_exact_return->format != XcmsCIEXYZFormat) { + if (_XcmsDIConvertColors(ccc, pColor_exact_return, + &dbWhitePt, 1, XcmsCIEXYZFormat) == XcmsFailure) { + return(XcmsFailure); + } + } + return (_XcmsDDConvertColors(ccc, pColor_exact_return, 1, + result_format, (Bool *)NULL)); + } + } else { + /* + * Target format is Device-Independent + * Therefore, DI --> DI conversion + */ + if (ccc->whitePtAdjProc && !_XcmsEqualWhitePts(ccc, + &dbWhitePt, pClientWhitePt)) { + /* + * The calling routine wants to resolve this color + * in terms if it's white point (i.e. Client White Point). + * Therefore, apply white adjustment for the displacement + * between dbWhitePt to clientWhitePt. + */ + return((*ccc->whitePtAdjProc)(ccc, &dbWhitePt, + pClientWhitePt, result_format, + pColor_exact_return, 1, (Bool *)NULL)); + } else if (_XcmsEqualWhitePts(ccc, + &dbWhitePt, pClientWhitePt)) { + /* + * Can use either dbWhitePt or pClientWhitePt to + * convert to the result_format. + */ + if (pColor_exact_return->format == result_format) { + return(XcmsSuccess); + } else { + return (_XcmsDIConvertColors(ccc, pColor_exact_return, + &dbWhitePt, 1, result_format)); + } + } else { + /* + * Need to convert to a white point independent color + * space (let's choose CIEXYZ) then convert to the + * target color space. Why? Lets assume that + * pColor_exact_return->format and result format + * are white point dependent format (e.g., CIELUV, CIELAB, + * TekHVC ... same or any combination). If so, we'll + * need to convert the color with dbWhitePt to an absolute + * spec (i.e. non-white point dependent) then convert that + * absolute value with clientWhitePt to the result_format. + */ + if (pColor_exact_return->format != XcmsCIEXYZFormat) { + if (_XcmsDIConvertColors(ccc, pColor_exact_return, + &dbWhitePt, 1, XcmsCIEXYZFormat) == XcmsFailure) { + return(XcmsFailure); + } + } + if (result_format == XcmsCIEXYZFormat) { + return(XcmsSuccess); + } else { + return(_XcmsDIConvertColors(ccc, pColor_exact_return, + pClientWhitePt, 1, result_format)); + } + } + } + } +} diff --git a/src/xcms/cmsGlobls.c b/src/xcms/cmsGlobls.c new file mode 100644 index 00000000..deeea982 --- /dev/null +++ b/src/xcms/cmsGlobls.c @@ -0,0 +1,160 @@ +/*$Xorg: cmsGlobls.c,v 1.3 2000/08/17 19:45:09 cpqbld Exp $ */ + +/* + * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. + * All Rights Reserved + * + * This file is a component of an X Window System-specific implementation + * of Xcms based on the TekColor Color Management System. Permission is + * hereby granted to use, copy, modify, sell, and otherwise distribute this + * software and its documentation for any purpose and without fee, provided + * that this copyright, permission, and disclaimer notice is reproduced in + * all copies of this software and in supporting documentation. TekColor + * is a trademark of Tektronix, Inc. + * + * Tektronix makes no representation about the suitability of this software + * for any purpose. It is provided "as is" and with all faults. + * + * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, + * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX 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 THE PERFORMANCE OF THIS SOFTWARE. + * + * + * NAME + * XcmsGlobls.c + * + * DESCRIPTION + * Source file containing Xcms globals + * + * + */ + +#include "Xlibint.h" +#include "Xcmsint.h" + +/* + * EXTERNS + * External declarations required locally to this package + * that are not already declared in any of the included header + * files (external includes or internal includes). + */ +extern XcmsFunctionSet XcmsLinearRGBFunctionSet; +#ifdef GRAY +extern XcmsFunctionSet XcmsGrayFunctionSet; +#endif /* GRAY */ + +/* UNDEFINED Color Space */ +extern XcmsColorSpace XcmsUNDEFINEDColorSpace; + +/* CIE XYZ Color Space */ +extern XcmsColorSpace XcmsCIEXYZColorSpace; + +/* CIE uvY Color Space */ +extern XcmsColorSpace XcmsCIEuvYColorSpace; + +/* CIE xyY Color Space */ +extern XcmsColorSpace XcmsCIExyYColorSpace; + +/* CIE Lab Color Space */ +extern XcmsColorSpace XcmsCIELabColorSpace; + +/* CIE Luv Color Space */ +extern XcmsColorSpace XcmsCIELuvColorSpace; + +/* TekHVC Color Space */ +extern XcmsColorSpace XcmsTekHVCColorSpace; + +/* Device Dependent Color Space Structures */ +extern XcmsColorSpace XcmsRGBiColorSpace; +extern XcmsColorSpace XcmsRGBColorSpace; + + +/* + * GLOBALS + * Variables declared in this package that are allowed + * to be used globally. + */ + + /* + * Initial array of Device Independent Color Spaces + */ +XcmsColorSpace *_XcmsDIColorSpacesInit[] = { + &XcmsCIEXYZColorSpace, + &XcmsCIEuvYColorSpace, + &XcmsCIExyYColorSpace, + &XcmsCIELabColorSpace, + &XcmsCIELuvColorSpace, + &XcmsTekHVCColorSpace, + &XcmsUNDEFINEDColorSpace, + NULL +}; + /* + * Pointer to the array of pointers to XcmsColorSpace structures for + * Device-Independent Color Spaces that are currently accessible by + * the color management system. End of list is indicated by a NULL pointer. + */ +XcmsColorSpace **_XcmsDIColorSpaces = _XcmsDIColorSpacesInit; + + /* + * Initial array of Device Dependent Color Spaces + */ +XcmsColorSpace *_XcmsDDColorSpacesInit[] = { + &XcmsRGBColorSpace, + &XcmsRGBiColorSpace, + NULL +}; + /* + * Pointer to the array of pointers to XcmsColorSpace structures for + * Device-Dependent Color Spaces that are currently accessible by + * the color management system. End of list is indicated by a NULL pointer. + */ +XcmsColorSpace **_XcmsDDColorSpaces = &_XcmsDDColorSpacesInit[0]; + + /* + * Initial array of Screen Color Characterization Function Sets + */ +XcmsFunctionSet *_XcmsSCCFuncSetsInit[] = { + &XcmsLinearRGBFunctionSet, +#ifdef GRAY + &XcmsGrayFunctionSet, +#endif /* GRAY */ + NULL}; + /* + * Pointer to the array of pointers to XcmsSCCFuncSet structures + * (Screen Color Characterization Function Sets) that are currently + * accessible by the color management system. End of list is + * indicated by a NULL pointer. + */ +XcmsFunctionSet **_XcmsSCCFuncSets = _XcmsSCCFuncSetsInit; + + /* + * X Consortium Registered Device-Independent Color Spaces + * Note that prefix must be in lowercase. + */ +char _XcmsCIEXYZ_prefix[] = "ciexyz"; +char _XcmsCIEuvY_prefix[] = "cieuvy"; +char _XcmsCIExyY_prefix[] = "ciexyy"; +char _XcmsCIELab_prefix[] = "cielab"; +char _XcmsCIELuv_prefix[] = "cieluv"; +char _XcmsTekHVC_prefix[] = "tekhvc"; + /* + * Registered Device-Dependent Color Spaces + */ +char _XcmsRGBi_prefix[] = "rgbi"; +char _XcmsRGB_prefix[] = "rgb"; + +XcmsRegColorSpaceEntry _XcmsRegColorSpaces[] = { + _XcmsCIEXYZ_prefix, XcmsCIEXYZFormat, + _XcmsCIEuvY_prefix, XcmsCIEuvYFormat, + _XcmsCIExyY_prefix, XcmsCIExyYFormat, + _XcmsCIELab_prefix, XcmsCIELabFormat, + _XcmsCIELuv_prefix, XcmsCIELuvFormat, + _XcmsTekHVC_prefix, XcmsTekHVCFormat, + _XcmsRGB_prefix, XcmsRGBFormat, + _XcmsRGBi_prefix, XcmsRGBiFormat, + NULL, 0 +}; diff --git a/src/xcms/cmsInt.c b/src/xcms/cmsInt.c new file mode 100644 index 00000000..b70e2c08 --- /dev/null +++ b/src/xcms/cmsInt.c @@ -0,0 +1,420 @@ +/* $Xorg: cmsInt.c,v 1.4 2000/08/17 19:45:09 cpqbld Exp $ */ + +/* + * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. + * All Rights Reserved + * + * This file is a component of an X Window System-specific implementation + * of Xcms based on the TekColor Color Management System. Permission is + * hereby granted to use, copy, modify, sell, and otherwise distribute this + * software and its documentation for any purpose and without fee, provided + * that this copyright, permission, and disclaimer notice is reproduced in + * all copies of this software and in supporting documentation. TekColor + * is a trademark of Tektronix, Inc. + * + * Tektronix makes no representation about the suitability of this software + * for any purpose. It is provided "as is" and with all faults. + * + * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, + * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX 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 THE PERFORMANCE OF THIS SOFTWARE. + * + * + * NAME + * XcmsInt.c - Xcms API utility routines + * + * DESCRIPTION + * Xcms Application Program Interface (API) utility + * routines for hanging information directly onto + * the Display structure. + * + * + */ + +/* #define NEED_EVENTS */ +#include <stdio.h> +#include "Xlibint.h" +#include "Xcmsint.h" + +#ifndef XCMSCOMPPROC +# define XCMSCOMPPROC XcmsTekHVCClipC +#endif + +/* + * EXTERNS + */ +extern XcmsColorSpace **_XcmsDIColorSpaces; +extern XcmsFunctionSet **_XcmsSCCFuncSets; + +static void _XcmsFreeDefaultCCCs(); + +/* + * GLOBALS + */ + + + +/************************************************************************ + * * + * API PRIVATE ROUTINES * + * * + ************************************************************************/ + +/* + * NAME + * _XcmsCopyPointerArray + * + * SYNOPSIS + */ +XPointer * +_XcmsCopyPointerArray(pap) + XPointer *pap; +/* + * DESCRIPTION + * Copies an array of NULL terminated pointers. + * + * RETURNS + * Returns NULL if failed; otherwise the address to + * the copy. + * + */ +{ + XPointer *newArray; + char **tmp; + int n; + + for (tmp = pap, n = 0; *tmp != NULL; tmp++, n++); + n++; /* add 1 to include the NULL pointer */ + + if ((newArray = (XPointer *)Xmalloc(n * sizeof(XPointer)))) { + memcpy((char *)newArray, (char *)pap, + (unsigned)(n * sizeof(XPointer))); + } + return((XPointer *)newArray); +} + +/* + * NAME + * _XcmsFreePointerArray + * + * SYNOPSIS + */ +void +_XcmsFreePointerArray(pap) + XPointer *pap; +/* + * DESCRIPTION + * Frees an array of NULL terminated pointers. + * + * RETURNS + * void + * + */ +{ + Xfree(pap); +} + +/* + * NAME + * _XcmsPushPointerArray + * + * SYNOPSIS + */ +XPointer * +_XcmsPushPointerArray(pap, p, papNoFree) + XPointer *pap; + XPointer p; + XPointer *papNoFree; +/* + * DESCRIPTION + * Places the specified pointer at the head of an array of NULL + * terminated pointers. + * + * RETURNS + * Returns NULL if failed; otherwise the address to + * the head of the array. + * + */ +{ + XPointer *newArray; + char **tmp; + int n; + + for (tmp = pap, n = 0; *tmp != NULL; tmp++, n++); + + /* add 2: 1 for the new pointer and another for the NULL pointer */ + n += 2; + + if ((newArray = (XPointer *)Xmalloc(n * sizeof(XPointer)))) { + memcpy((char *)(newArray+1),(char *)pap, + (unsigned)((n-1) * sizeof(XPointer))); + *newArray = p; + } + if (pap != papNoFree) { + _XcmsFreePointerArray(pap); + } + return((XPointer *)newArray); +} + +/* + * NAME + * _XcmsInitDefaultCCCs + * + * SYNOPSIS + */ +int +_XcmsInitDefaultCCCs(dpy) + Display *dpy; +/* + * DESCRIPTION + * Initializes the Xcms per Display Info structure + * (XcmsPerDpyInfo). + * + * RETURNS + * Returns 0 if failed; otherwise non-zero. + * + */ +{ + int nScrn = ScreenCount(dpy); + int i; + XcmsCCC ccc; + + if (nScrn <= 0) { + return(0); + } + + /* + * Create an array of XcmsCCC structures, one for each screen. + * They serve as the screen's default CCC. + */ + if (!(ccc = (XcmsCCC) + Xcalloc((unsigned)nScrn, (unsigned) sizeof(XcmsCCCRec)))) { + return(0); + } + dpy->cms.defaultCCCs = (XPointer)ccc; + dpy->free_funcs->defaultCCCs = _XcmsFreeDefaultCCCs; + + for (i = 0; i < nScrn; i++, ccc++) { + ccc->dpy = dpy; + ccc->screenNumber = i; + ccc->visual = DefaultVisual(dpy, i); + /* + * Used calloc to allocate memory so: + * ccc->clientWhitePt->format == XcmsUndefinedFormat + * ccc->gamutCompProc == NULL + * ccc->whitePtAdjProc == NULL + * ccc->pPerScrnInfo = NULL + * + * Don't need to create XcmsPerScrnInfo and its functionSet and + * pScreenData components until the default CCC is accessed. + * Note that the XcmsDefaultCCC routine calls _XcmsInitScrnInto + * to do this. + */ + ccc->gamutCompProc = XCMSCOMPPROC; + } + + return(1); +} + + +/* + * NAME + * _XcmsFreeDefaultCCCs - Free Default CCCs and its PerScrnInfo + * + * SYNOPSIS + */ +static void +_XcmsFreeDefaultCCCs(dpy) + Display *dpy; +/* + * DESCRIPTION + * This routine frees the default XcmsCCC's associated with + * each screen and its associated substructures as neccessary. + * + * RETURNS + * void + * + * + */ +{ + int nScrn = ScreenCount(dpy); + XcmsCCC ccc; + int i; + + /* + * Free Screen data in each DefaultCCC + * Do not use XcmsFreeCCC here because it will not free + * DefaultCCC's. + */ + ccc = (XcmsCCC)dpy->cms.defaultCCCs; + for (i = nScrn; i--; ccc++) { + /* + * Check if XcmsPerScrnInfo exists. + * + * This is the only place where XcmsPerScrnInfo structures + * are freed since there is only one allocated per Screen. + * It just so happens that we place its reference in the + * default CCC. + */ + if (ccc->pPerScrnInfo) { + /* Check if SCCData exists */ + if (ccc->pPerScrnInfo->state != XcmsInitNone + && ccc->pPerScrnInfo->screenData) { + (*((XcmsFunctionSet *)ccc->pPerScrnInfo->functionSet)->screenFreeProc) + (ccc->pPerScrnInfo->screenData); + } + Xfree(ccc->pPerScrnInfo); + } + } + + /* + * Free the array of XcmsCCC structures + */ + Xfree(dpy->cms.defaultCCCs); + dpy->cms.defaultCCCs = (XPointer)NULL; +} + + + +/* + * NAME + * _XcmsInitScrnInfo + * + * SYNOPSIS + */ +int +_XcmsInitScrnInfo(dpy, screenNumber) + register Display *dpy; + int screenNumber; +/* + * DESCRIPTION + * Given a display and screen number, this routine attempts + * to initialize the Xcms per Screen Info structure + * (XcmsPerScrnInfo). + * + * RETURNS + * Returns zero if initialization failed; non-zero otherwise. + */ +{ + XcmsFunctionSet **papSCCFuncSet = _XcmsSCCFuncSets; + XcmsCCC defaultccc; + + /* + * Check if the XcmsCCC's for each screen has been created. + * Really dont need to be created until some routine uses the Xcms + * API routines. + */ + if ((XcmsCCC)dpy->cms.defaultCCCs == NULL) { + if (!_XcmsInitDefaultCCCs(dpy)) { + return(0); + } + } + + defaultccc = (XcmsCCC)dpy->cms.defaultCCCs + screenNumber; + + /* + * For each SCCFuncSet, try its pInitScrnFunc. + * If the function succeeds, then we got it! + */ + + if (!defaultccc->pPerScrnInfo) { + /* + * This is one of two places where XcmsPerScrnInfo structures + * are allocated. There is one allocated per Screen that is + * shared among visuals that do not have specific intensity + * tables. Other XcmsPerScrnInfo structures are created + * for the latter (see XcmsCreateCCC). The ones created + * here are referenced by the default CCC. + */ + if (!(defaultccc->pPerScrnInfo = (XcmsPerScrnInfo *) + Xcalloc(1, (unsigned) sizeof(XcmsPerScrnInfo)))) { + return(0); + } + defaultccc->pPerScrnInfo->state = XcmsInitNone; + } + + while (*papSCCFuncSet != NULL) { + if ((*(*papSCCFuncSet)->screenInitProc)(dpy, screenNumber, + defaultccc->pPerScrnInfo)) { + defaultccc->pPerScrnInfo->state = XcmsInitSuccess; + return(1); + } + papSCCFuncSet++; + } + + /* + * Use Default SCCData + */ + return(_XcmsLRGB_InitScrnDefault(dpy, screenNumber, defaultccc->pPerScrnInfo)); +} + + +/* + * NAME + * _XcmsFreeIntensityMaps + * + * SYNOPSIS + */ +void +_XcmsFreeIntensityMaps(dpy) + Display *dpy; +/* + * DESCRIPTION + * Frees all XcmsIntensityMap structures in the linked list + * and sets dpy->cms.perVisualIntensityMaps to NULL. + * + * RETURNS + * void + * + */ +{ + XcmsIntensityMap *pNext, *pFree; + + pNext = (XcmsIntensityMap *)dpy->cms.perVisualIntensityMaps; + while (pNext != NULL) { + pFree = pNext; + pNext = pNext->pNext; + (*pFree->pFreeScreenData)(pFree->screenData); + /* Now free the XcmsIntensityMap structure */ + Xfree(pFree); + } + dpy->cms.perVisualIntensityMaps = (XPointer)NULL; +} + + +/* + * NAME + * _XcmsGetIntensityMap + * + * SYNOPSIS + */ +XcmsIntensityMap * +_XcmsGetIntensityMap(dpy, visual) + Display *dpy; + Visual *visual; +/* + * DESCRIPTION + * Attempts to return a per-Visual intensity map. + * + * RETURNS + * Pointer to the XcmsIntensityMap structure if found; + * otherwise NULL + * + */ +{ + VisualID targetID = visual->visualid; + XcmsIntensityMap *pNext; + + pNext = (XcmsIntensityMap *)dpy->cms.perVisualIntensityMaps; + while (pNext != NULL) { + if (targetID == pNext->visualID) { + return(pNext); + } + pNext = pNext->pNext; + } + return((XcmsIntensityMap *)NULL); +} diff --git a/src/xcms/cmsLkCol.c b/src/xcms/cmsLkCol.c new file mode 100644 index 00000000..eb9669ff --- /dev/null +++ b/src/xcms/cmsLkCol.c @@ -0,0 +1,213 @@ +/* $Xorg: cmsLkCol.c,v 1.3 2000/08/17 19:45:09 cpqbld Exp $ */ + +/* + * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. + * All Rights Reserved + * + * This file is a component of an X Window System-specific implementation + * of Xcms based on the TekColor Color Management System. Permission is + * hereby granted to use, copy, modify, sell, and otherwise distribute this + * software and its documentation for any purpose and without fee, provided + * that this copyright, permission, and disclaimer notice is reproduced in + * all copies of this software and in supporting documentation. TekColor + * is a trademark of Tektronix, Inc. + * + * Tektronix makes no representation about the suitability of this software + * for any purpose. It is provided "as is" and with all faults. + * + * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, + * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX 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 THE PERFORMANCE OF THIS SOFTWARE. + * + * + * NAME + * XcmsLkCol.c + * + * DESCRIPTION + * Source for XcmsLookupColor + * + * + */ + +#define NEED_REPLIES +#include <stdio.h> +#include "Xlibint.h" +#include "Xcmsint.h" + +/* + * EXTERNS + */ +extern void _XColor_to_XcmsRGB(); +extern void _XcmsRGB_to_XColor(); +extern void _XcmsResolveColor(); +extern void _XcmsUnresolveColor(); +#ifdef X_NOT_STDC_ENV +extern char *getenv(); +#endif + +/* + * NAME + * XcmsLookupColor - + * + * SYNOPSIS + */ +#if NeedFunctionPrototypes +Status +XcmsLookupColor ( + Display *dpy, + Colormap cmap, + _Xconst char *colorname, + XcmsColor *pColor_exact_return, + XcmsColor *pColor_scrn_return, + XcmsColorFormat result_format) +#else +Status +XcmsLookupColor(dpy, cmap, colorname, pColor_exact_return, pColor_scrn_return, + result_format) + Display *dpy; + Colormap cmap; + char *colorname; + XcmsColor *pColor_exact_return; + XcmsColor *pColor_scrn_return; + XcmsColorFormat result_format; +#endif +/* + * DESCRIPTION + * The XcmsLookupColor function finds the color specification + * associated with a color name in the Device-Independent Color + * Name Database. + * RETURNS + * This function returns both the color specification found in the + * database (db specification) and the color specification for the + * color displayable by the specified screen (screen + * specification). The calling routine sets the format for these + * returned specifications in the XcmsColor format component. + * If XcmsUndefinedFormat, the specification is returned in the + * format used to store the color in the database. + */ +{ + Status retval1 = XcmsSuccess; + Status retval2 = XcmsSuccess; + XcmsCCC ccc; + register int n; + xLookupColorReply reply; + register xLookupColorReq *req; + XColor def, scr; + +/* + * 0. Check for invalid arguments. + */ + if (dpy == NULL || colorname[0] == '\0' || pColor_scrn_return == 0 + || pColor_exact_return == NULL) { + return(XcmsFailure); + } + + if ((ccc = XcmsCCCOfColormap(dpy, cmap)) == (XcmsCCC)NULL) { + return(XcmsFailure); + } + +/* + * 1. Convert string to a XcmsColor + */ + if ((retval1 = _XcmsResolveColorString(ccc, &colorname, + pColor_exact_return, result_format)) == XcmsFailure) { + return(XcmsFailure); + } + if (retval1 == _XCMS_NEWNAME) { + goto PassToServer; + } + +/* + * 2. pColor_scrn_return + * Assume the pColor_exact_return has already been adjusted to + * the Client White Point. + * + */ + /* + * Convert to RGB, adjusting for white point differences if necessary. + */ + memcpy((char *)pColor_scrn_return, (char *)pColor_exact_return, + sizeof(XcmsColor)); + if (pColor_scrn_return->format == XcmsRGBFormat) { + retval2 = XcmsSuccess; + } else if ((retval2 = XcmsConvertColors(ccc, pColor_scrn_return, 1, + XcmsRGBFormat, (Bool *)NULL)) == XcmsFailure) { + return(XcmsFailure); + } + + /* + * Then, convert XcmsColor structure to the target specification + * format. Note that we must use NULL instead of passing + * pCompressed. + */ + + if (result_format == XcmsUndefinedFormat) { + result_format = pColor_exact_return->format; + } + if (result_format == XcmsRGBFormat) { + _XcmsUnresolveColor(ccc, pColor_scrn_return); + } else { + _XcmsResolveColor(ccc, pColor_scrn_return); + if (XcmsConvertColors(ccc, pColor_scrn_return, 1, result_format, + (Bool *) NULL) == XcmsFailure) { + return(XcmsFailure); + } + } + + return(retval1 > retval2 ? retval1 : retval2); + +PassToServer: + /* + * Xcms and i18n methods failed, so lets pass it to the server + * for parsing. + */ + + LockDisplay(dpy); + GetReq (LookupColor, req); + req->cmap = cmap; + req->nbytes = n = strlen(colorname); + req->length += (n + 3) >> 2; + Data (dpy, colorname, (long)n); + if (!_XReply (dpy, (xReply *) &reply, 0, xTrue)) { + UnlockDisplay(dpy); + SyncHandle(); + return (XcmsFailure); + } + def.red = reply.exactRed; + def.green = reply.exactGreen; + def.blue = reply.exactBlue; + + scr.red = reply.screenRed; + scr.green = reply.screenGreen; + scr.blue = reply.screenBlue; + + UnlockDisplay(dpy); + SyncHandle(); + + _XColor_to_XcmsRGB(ccc, &def, pColor_exact_return, 1); + _XColor_to_XcmsRGB(ccc, &scr, pColor_scrn_return, 1); + + /* + * Then, convert XcmsColor structure to the target specification + * format. Note that we must use NULL instead of passing + * pCompressed. + */ + + if (result_format != XcmsRGBFormat + && result_format != XcmsUndefinedFormat) { + if (XcmsConvertColors(ccc, pColor_exact_return, 1, result_format, + (Bool *) NULL) == XcmsFailure) { + return(XcmsFailure); + } + if (XcmsConvertColors(ccc, pColor_scrn_return, 1, result_format, + (Bool *) NULL) == XcmsFailure) { + return(XcmsFailure); + } + } + + return(XcmsSuccess); +} diff --git a/src/xcms/cmsMath.c b/src/xcms/cmsMath.c new file mode 100644 index 00000000..fd09cec1 --- /dev/null +++ b/src/xcms/cmsMath.c @@ -0,0 +1,138 @@ +/* $Xorg: cmsMath.c,v 1.4 2001/02/09 02:03:39 xorgcvs Exp $ */ + +/* + +Copyright 1990, 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. + +*/ + +/* + * Stephen Gildea, MIT X Consortium, January 1991 + */ + +#include "Xlibint.h" +#include "Xcmsint.h" + +#if !defined(X_NOT_STDC_ENV) && (defined(__STDC__) || !(defined(sun) || (defined(sony) && !defined(SYSTYPE_SYSV) && !defined(_SYSTYPE_SYSV)))) +#include <float.h> +#endif +#ifndef DBL_EPSILON +#define DBL_EPSILON 1e-6 +#endif + +#ifdef _X_ROOT_STATS +int cbrt_loopcount; +int sqrt_loopcount; +#endif + +/* Newton's Method: x_n+1 = x_n - ( f(x_n) / f'(x_n) ) */ + + +/* for cube roots, x^3 - a = 0, x_new = x - 1/3 (x - a/x^2) */ + +double +_XcmsCubeRoot(a) + double a; +{ + register double abs_a, cur_guess, delta; + +#ifdef DEBUG + printf("_XcmsCubeRoot passed in %g\n", a); +#endif +#ifdef _X_ROOT_STATS + cbrt_loopcount = 0; +#endif + if (a == 0.) + return 0.; + + abs_a = a<0. ? -a : a; /* convert to positive to speed loop tests */ + + /* arbitrary first guess */ + if (abs_a > 1.) + cur_guess = abs_a/8.; + else + cur_guess = abs_a*8.; + + do { +#ifdef _X_ROOT_STATS + cbrt_loopcount++; +#endif + delta = (cur_guess - abs_a/(cur_guess*cur_guess))/3.; + cur_guess -= delta; + if (delta < 0.) delta = -delta; + } while (delta >= cur_guess*DBL_EPSILON); + + if (a < 0.) + cur_guess = -cur_guess; + +#ifdef DEBUG + printf("_XcmsCubeRoot returning %g\n", cur_guess); +#endif + return cur_guess; +} + + + +/* for square roots, x^2 - a = 0, x_new = x - 1/2 (x - a/x) */ + +double +_XcmsSquareRoot(a) + double a; +{ + register double cur_guess, delta; + +#ifdef DEBUG + printf("_XcmsSquareRoot passed in %g\n", a); +#endif +#ifdef _X_ROOT_STATS + sqrt_loopcount = 0; +#endif + if (a == 0.) + return 0.; + + if (a < 0.) { + /* errno = EDOM; */ + return 0.; + } + + /* arbitrary first guess */ + if (a > 1.) + cur_guess = a/4.; + else + cur_guess = a*4.; + + do { +#ifdef _X_ROOT_STATS + sqrt_loopcount++; +#endif + delta = (cur_guess - a/cur_guess)/2.; + cur_guess -= delta; + if (delta < 0.) delta = -delta; + } while (delta >= cur_guess*DBL_EPSILON); + +#ifdef DEBUG + printf("_XcmsSquareRoot returning %g\n", cur_guess); +#endif + return cur_guess; +} + diff --git a/src/xcms/cmsProp.c b/src/xcms/cmsProp.c new file mode 100644 index 00000000..28d7a880 --- /dev/null +++ b/src/xcms/cmsProp.c @@ -0,0 +1,143 @@ +/* $Xorg: cmsProp.c,v 1.3 2000/08/17 19:45:10 cpqbld Exp $ */ + +/* + * + * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. + * All Rights Reserved + * + * This file is a component of an X Window System-specific implementation + * of Xcms based on the TekColor Color Management System. Permission is + * hereby granted to use, copy, modify, sell, and otherwise distribute this + * software and its documentation for any purpose and without fee, provided + * that this copyright, permission, and disclaimer notice is reproduced in + * all copies of this software and in supporting documentation. TekColor + * is a trademark of Tektronix, Inc. + * + * Tektronix makes no representation about the suitability of this software + * for any purpose. It is provided "as is" and with all faults. + * + * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, + * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX 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 THE PERFORMANCE OF THIS SOFTWARE. + * + * NAME + * XcmsProp.c + * + * DESCRIPTION + * This utility routines for manipulating properties. + * + */ + +#include <X11/Xatom.h> +#include "Xlibint.h" +#include "Xcmsint.h" + + +/************************************************************************ + * * + * API PRIVATE ROUTINES * + * * + ************************************************************************/ + + +/* + * NAME + * _XcmsGetElement -- get an element value from the property passed + * + * SYNOPSIS + */ +unsigned long +_XcmsGetElement (format, pValue, pCount) + int format; + char **pValue; + unsigned long *pCount; +/* + * DESCRIPTION + * Get the next element from the property and return it. + * Also increment the pointer the amount needed. + * + * Returns + * unsigned long + */ +{ + unsigned long value; + + switch (format) { + case 32: + value = *((unsigned long *)(*pValue)) & 0xFFFFFFFF; + *pValue += sizeof(unsigned long); + *pCount -= 1; + break; + case 16: + value = *((unsigned short *)(*pValue)); + *pValue += sizeof(unsigned short); + *pCount -= 1; + break; + case 8: + value = *((unsigned char *) (*pValue)); + *pValue += 1; + *pCount -= 1; + break; + default: + value = 0; + break; + } + return(value); +} + + +/* + * NAME + * _XcmsGetProperty -- Determine the existance of a property + * + * SYNOPSIS + */ +int +_XcmsGetProperty (pDpy, w, property, pFormat, pNItems, pNBytes, pValue) + Display *pDpy; + Window w; + Atom property; + int *pFormat; + unsigned long *pNItems; + unsigned long *pNBytes; + char **pValue; +/* + * DESCRIPTION + * + * Returns + * 0 if property does not exist. + * 1 if property exists. + */ +{ + char *prop_ret; + int format_ret; + long len = 6516; + unsigned long nitems_ret, after_ret; + Atom atom_ret; + + while (XGetWindowProperty (pDpy, w, property, 0, len, False, + XA_INTEGER, &atom_ret, &format_ret, + &nitems_ret, &after_ret, + (unsigned char **)&prop_ret)) { + if (after_ret > 0) { + len += nitems_ret * (format_ret >> 3); + XFree (prop_ret); + } else { + break; + } + } + if (format_ret == 0 || nitems_ret == 0) { + /* the property does not exist or is of an unexpected type */ + return(XcmsFailure); + } + + *pFormat = format_ret; + *pNItems = nitems_ret; + *pNBytes = nitems_ret * (format_ret >> 3); + *pValue = prop_ret; + return(XcmsSuccess); +} diff --git a/src/xcms/cmsTrig.c b/src/xcms/cmsTrig.c new file mode 100644 index 00000000..a1e9b50c --- /dev/null +++ b/src/xcms/cmsTrig.c @@ -0,0 +1,600 @@ +/* $Xorg: cmsTrig.c,v 1.3 2000/08/17 19:45:10 cpqbld Exp $ */ + +/* + * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. + * All Rights Reserved + * + * This file is a component of an X Window System-specific implementation + * of Xcms based on the TekColor Color Management System. Permission is + * hereby granted to use, copy, modify, sell, and otherwise distribute this + * software and its documentation for any purpose and without fee, provided + * that this copyright, permission, and disclaimer notice is reproduced in + * all copies of this software and in supporting documentation. TekColor + * is a trademark of Tektronix, Inc. + * + * Tektronix makes no representation about the suitability of this software + * for any purpose. It is provided "as is" and with all faults. + * + * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, + * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX 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 THE PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * It should be pointed out that for simplicity's sake, the + * environment parameters are defined as floating point constants, + * rather than octal or hexadecimal initializations of allocated + * storage areas. This means that the range of allowed numbers + * may not exactly match the hardware's capabilities. For example, + * if the maximum positive double precision floating point number + * is EXACTLY 1.11...E100 and the constant "MAXDOUBLE is + * defined to be 1.11E100 then the numbers between 1.11E100 and + * 1.11...E100 are considered to be undefined. For most + * applications, this will cause no problems. + * + * An alternate method is to allocate a global static "double" variable, + * say "maxdouble", and use a union declaration and initialization + * to initialize it with the proper bits for the EXACT maximum value. + * This was not done because the only compilers available to the + * author did not fully support union initialization features. + * + */ + +/* + * EXTERNS + */ +extern double _XcmsSquareRoot(); + +/* + * FORWARD DECLARATIONS + */ +double _XcmsCosine(); +static double _XcmsModulo(); +static double _XcmsModuloF(); +static double _XcmsPolynomial(); +double _XcmsSine(); +double _XcmsArcTangent(); + +/* + * DEFINES + */ + +#ifdef __STDC__ +#define Const const +#else +#define Const /**/ +#endif +#define XCMS_MAXERROR 0.000001 +#define XCMS_MAXITER 10000 +#define XCMS_PI 3.14159265358979323846264338327950 +#define XCMS_TWOPI 6.28318530717958620 +#define XCMS_HALFPI 1.57079632679489660 +#define XCMS_FOURTHPI 0.785398163397448280 +#define XCMS_SIXTHPI 0.523598775598298820 +#define XCMS_RADIANS(d) ((d) * XCMS_PI / 180.0) +#define XCMS_DEGREES(r) ((r) * 180.0 / XCMS_PI) +#define XCMS_X6_UNDERFLOWS (4.209340e-52) /* X**6 almost underflows */ +#define XCMS_X16_UNDERFLOWS (5.421010e-20) /* X**16 almost underflows*/ +#define XCMS_CHAR_BIT 8 +#define XCMS_LONG_MAX 0x7FFFFFFF +#define XCMS_DEXPLEN 11 +#define XCMS_NBITS(type) (XCMS_CHAR_BIT * (int)sizeof(type)) +#define XCMS_FABS(x) ((x) < 0.0 ? -(x) : (x)) + +/* XCMS_DMAXPOWTWO - largest power of two exactly representable as a double */ +#ifdef _CRAY +#define XCMS_DMAXPOWTWO ((double)(1 < 47)) +#else +#define XCMS_DMAXPOWTWO ((double)(XCMS_LONG_MAX) * \ + (1L << (XCMS_NBITS(double)-XCMS_DEXPLEN) - XCMS_NBITS(long) + 1)) +#endif + +/* + * LOCAL VARIABLES + */ + +static double Const cos_pcoeffs[] = { + 0.12905394659037374438e7, + -0.37456703915723204710e6, + 0.13432300986539084285e5, + -0.11231450823340933092e3 +}; + +static double Const cos_qcoeffs[] = { + 0.12905394659037373590e7, + 0.23467773107245835052e5, + 0.20969518196726306286e3, + 1.0 +}; + +static double Const sin_pcoeffs[] = { + 0.20664343336995858240e7, + -0.18160398797407332550e6, + 0.35999306949636188317e4, + -0.20107483294588615719e2 +}; + +static double Const sin_qcoeffs[] = { + 0.26310659102647698963e7, + 0.39270242774649000308e5, + 0.27811919481083844087e3, + 1.0 +}; + +/* + * + * FUNCTION + * + * _XcmsCosine double precision cosine + * + * KEY WORDS + * + * cos + * machine independent routines + * trigonometric functions + * math libraries + * + * DESCRIPTION + * + * Returns double precision cosine of double precision + * floating point argument. + * + * USAGE + * + * double _XcmsCosine (x) + * double x; + * + * REFERENCES + * + * Computer Approximations, J.F. Hart et al, John Wiley & Sons, + * 1968, pp. 112-120. + * + * RESTRICTIONS + * + * The sin and cos routines are interactive in the sense that + * in the process of reducing the argument to the range -PI/4 + * to PI/4, each may call the other. Ultimately one or the + * other uses a polynomial approximation on the reduced + * argument. The sin approximation has a maximum relative error + * of 10**(-17.59) and the cos approximation has a maximum + * relative error of 10**(-16.18). + * + * These error bounds assume exact arithmetic + * in the polynomial evaluation. Additional rounding and + * truncation errors may occur as the argument is reduced + * to the range over which the polynomial approximation + * is valid, and as the polynomial is evaluated using + * finite-precision arithmetic. + * + * PROGRAMMER + * + * Fred Fish + * + * INTERNALS + * + * Computes cos(x) from: + * + * (1) Reduce argument x to range -PI to PI. + * + * (2) If x > PI/2 then call cos recursively + * using relation cos(x) = -cos(x - PI). + * + * (3) If x < -PI/2 then call cos recursively + * using relation cos(x) = -cos(x + PI). + * + * (4) If x > PI/4 then call sin using + * relation cos(x) = sin(PI/2 - x). + * + * (5) If x < -PI/4 then call cos using + * relation cos(x) = sin(PI/2 + x). + * + * (6) If x would cause underflow in approx + * evaluation arithmetic then return + * sqrt(1.0 - x**2). + * + * (7) By now x has been reduced to range + * -PI/4 to PI/4 and the approximation + * from HART pg. 119 can be used: + * + * cos(x) = ( p(y) / q(y) ) + * Where: + * + * y = x * (4/PI) + * + * p(y) = SUM [ Pj * (y**(2*j)) ] + * over j = {0,1,2,3} + * + * q(y) = SUM [ Qj * (y**(2*j)) ] + * over j = {0,1,2,3} + * + * P0 = 0.12905394659037374438571854e+7 + * P1 = -0.3745670391572320471032359e+6 + * P2 = 0.134323009865390842853673e+5 + * P3 = -0.112314508233409330923e+3 + * Q0 = 0.12905394659037373590295914e+7 + * Q1 = 0.234677731072458350524124e+5 + * Q2 = 0.2096951819672630628621e+3 + * Q3 = 1.0000... + * (coefficients from HART table #3843 pg 244) + * + * + * **** NOTE **** The range reduction relations used in + * this routine depend on the final approximation being valid + * over the negative argument range in addition to the positive + * argument range. The particular approximation chosen from + * HART satisfies this requirement, although not explicitly + * stated in the text. This may not be true of other + * approximations given in the reference. + * + */ + +double _XcmsCosine (x) +double x; +{ + auto double y; + auto double yt2; + double retval; + + if (x < -XCMS_PI || x > XCMS_PI) { + x = _XcmsModulo (x, XCMS_TWOPI); + if (x > XCMS_PI) { + x = x - XCMS_TWOPI; + } else if (x < -XCMS_PI) { + x = x + XCMS_TWOPI; + } + } + if (x > XCMS_HALFPI) { + retval = -(_XcmsCosine (x - XCMS_PI)); + } else if (x < -XCMS_HALFPI) { + retval = -(_XcmsCosine (x + XCMS_PI)); + } else if (x > XCMS_FOURTHPI) { + retval = _XcmsSine (XCMS_HALFPI - x); + } else if (x < -XCMS_FOURTHPI) { + retval = _XcmsSine (XCMS_HALFPI + x); + } else if (x < XCMS_X6_UNDERFLOWS && x > -XCMS_X6_UNDERFLOWS) { + retval = _XcmsSquareRoot (1.0 - (x * x)); + } else { + y = x / XCMS_FOURTHPI; + yt2 = y * y; + retval = _XcmsPolynomial (3, cos_pcoeffs, yt2) / _XcmsPolynomial (3, cos_qcoeffs, yt2); + } + return (retval); +} + + +/* + * FUNCTION + * + * _XcmsModulo double precision modulo + * + * KEY WORDS + * + * _XcmsModulo + * machine independent routines + * math libraries + * + * DESCRIPTION + * + * Returns double precision modulo of two double + * precision arguments. + * + * USAGE + * + * double _XcmsModulo (value, base) + * double value; + * double base; + * + * PROGRAMMER + * + * Fred Fish + * + */ +static double _XcmsModulo (value, base) +double value; +double base; +{ + auto double intpart; + + value /= base; + value = _XcmsModuloF (value, &intpart); + value *= base; + return(value); +} + + +/* + * frac = (double) _XcmsModuloF(double val, double *dp) + * return fractional part of 'val' + * set *dp to integer part of 'val' + * + * Note -> only compiled for the CA or KA. For the KB/MC, + * "math.c" instantiates a copy of the inline function + * defined in "math.h". + */ +static double +_XcmsModuloF(val, dp) +double val; +register double *dp; +{ + register double abs; + register double ip; + + /* should check for illegal values here - nan, inf, etc */ + abs = XCMS_FABS(val); + if (abs >= XCMS_DMAXPOWTWO) { + ip = val; + } else { + ip = abs + XCMS_DMAXPOWTWO; /* dump fraction */ + ip -= XCMS_DMAXPOWTWO; /* restore w/o frac */ + if (ip > abs) /* if it rounds up */ + ip -= 1.0; /* fix it */ + ip = XCMS_FABS(ip); + } + *dp = ip; + return (val - ip); /* signed fractional part */ +} + + +/* + * FUNCTION + * + * _XcmsPolynomial double precision polynomial evaluation + * + * KEY WORDS + * + * poly + * machine independent routines + * math libraries + * + * DESCRIPTION + * + * Evaluates a polynomial and returns double precision + * result. Is passed a the order of the polynomial, + * a pointer to an array of double precision polynomial + * coefficients (in ascending order), and the independent + * variable. + * + * USAGE + * + * double _XcmsPolynomial (order, coeffs, x) + * int order; + * double *coeffs; + * double x; + * + * PROGRAMMER + * + * Fred Fish + * + * INTERNALS + * + * Evalates the polynomial using recursion and the form: + * + * P(x) = P0 + x(P1 + x(P2 +...x(Pn))) + * + */ + +static double _XcmsPolynomial (order, coeffs, x) +register int order; +double Const *coeffs; +double x; +{ + auto double rtn_value; + +#if 0 + auto double curr_coeff; + if (order <= 0) { + rtn_value = *coeffs; + } else { + curr_coeff = *coeffs; /* Bug in Unisoft's compiler. Does not */ + coeffs++; /* generate good code for *coeffs++ */ + rtn_value = curr_coeff + x * _XcmsPolynomial (--order, coeffs, x); + } +#else /* ++jrb -- removed tail recursion */ + coeffs += order; + rtn_value = *coeffs--; + while(order-- > 0) + rtn_value = *coeffs-- + (x * rtn_value); +#endif + + return(rtn_value); +} + + +/* + * FUNCTION + * + * _XcmsSine double precision sine + * + * KEY WORDS + * + * sin + * machine independent routines + * trigonometric functions + * math libraries + * + * DESCRIPTION + * + * Returns double precision sine of double precision + * floating point argument. + * + * USAGE + * + * double _XcmsSine (x) + * double x; + * + * REFERENCES + * + * Computer Approximations, J.F. Hart et al, John Wiley & Sons, + * 1968, pp. 112-120. + * + * RESTRICTIONS + * + * The sin and cos routines are interactive in the sense that + * in the process of reducing the argument to the range -PI/4 + * to PI/4, each may call the other. Ultimately one or the + * other uses a polynomial approximation on the reduced + * argument. The sin approximation has a maximum relative error + * of 10**(-17.59) and the cos approximation has a maximum + * relative error of 10**(-16.18). + * + * These error bounds assume exact arithmetic + * in the polynomial evaluation. Additional rounding and + * truncation errors may occur as the argument is reduced + * to the range over which the polynomial approximation + * is valid, and as the polynomial is evaluated using + * finite-precision arithmetic. + * + * PROGRAMMER + * + * Fred Fish + * + * INTERNALS + * + * Computes sin(x) from: + * + * (1) Reduce argument x to range -PI to PI. + * + * (2) If x > PI/2 then call sin recursively + * using relation sin(x) = -sin(x - PI). + * + * (3) If x < -PI/2 then call sin recursively + * using relation sin(x) = -sin(x + PI). + * + * (4) If x > PI/4 then call cos using + * relation sin(x) = cos(PI/2 - x). + * + * (5) If x < -PI/4 then call cos using + * relation sin(x) = -cos(PI/2 + x). + * + * (6) If x is small enough that polynomial + * evaluation would cause underflow + * then return x, since sin(x) + * approaches x as x approaches zero. + * + * (7) By now x has been reduced to range + * -PI/4 to PI/4 and the approximation + * from HART pg. 118 can be used: + * + * sin(x) = y * ( p(y) / q(y) ) + * Where: + * + * y = x * (4/PI) + * + * p(y) = SUM [ Pj * (y**(2*j)) ] + * over j = {0,1,2,3} + * + * q(y) = SUM [ Qj * (y**(2*j)) ] + * over j = {0,1,2,3} + * + * P0 = 0.206643433369958582409167054e+7 + * P1 = -0.18160398797407332550219213e+6 + * P2 = 0.359993069496361883172836e+4 + * P3 = -0.2010748329458861571949e+2 + * Q0 = 0.263106591026476989637710307e+7 + * Q1 = 0.3927024277464900030883986e+5 + * Q2 = 0.27811919481083844087953e+3 + * Q3 = 1.0000... + * (coefficients from HART table #3063 pg 234) + * + * + * **** NOTE **** The range reduction relations used in + * this routine depend on the final approximation being valid + * over the negative argument range in addition to the positive + * argument range. The particular approximation chosen from + * HART satisfies this requirement, although not explicitly + * stated in the text. This may not be true of other + * approximations given in the reference. + * + */ + +double +_XcmsSine (x) +double x; +{ + double y; + double yt2; + double retval; + + if (x < -XCMS_PI || x > XCMS_PI) { + x = _XcmsModulo (x, XCMS_TWOPI); + if (x > XCMS_PI) { + x = x - XCMS_TWOPI; + } else if (x < -XCMS_PI) { + x = x + XCMS_TWOPI; + } + } + if (x > XCMS_HALFPI) { + retval = -(_XcmsSine (x - XCMS_PI)); + } else if (x < -XCMS_HALFPI) { + retval = -(_XcmsSine (x + XCMS_PI)); + } else if (x > XCMS_FOURTHPI) { + retval = _XcmsCosine (XCMS_HALFPI - x); + } else if (x < -XCMS_FOURTHPI) { + retval = -(_XcmsCosine (XCMS_HALFPI + x)); + } else if (x < XCMS_X6_UNDERFLOWS && x > -XCMS_X6_UNDERFLOWS) { + retval = x; + } else { + y = x / XCMS_FOURTHPI; + yt2 = y * y; + retval = y * (_XcmsPolynomial (3, sin_pcoeffs, yt2) / _XcmsPolynomial(3, sin_qcoeffs, yt2)); + } + return(retval); +} + + +/* + * NAME + * _XcmsArcTangent + * + * SYNOPSIS + */ +double +_XcmsArcTangent(x) + double x; +/* + * DESCRIPTION + * Computes the arctangent. + * This is an implementation of the Gauss algorithm as + * described in: + * Forman S. Acton, Numerical Methods That Work, + * New York, NY, Harper & Row, 1970. + * + * RETURNS + * Returns the arctangent + */ +{ + double ai, a1, bi, b1, l, d; + double maxerror; + int i; + + if (x == 0.0) { + return (0.0); + } + if (x < 1.0) { + maxerror = x * XCMS_MAXERROR; + } else { + maxerror = XCMS_MAXERROR; + } + ai = _XcmsSquareRoot( 1.0 / (1.0 + (x * x)) ); + bi = 1.0; + for (i = 0; i < XCMS_MAXITER; i++) { + a1 = (ai + bi) / 2.0; + b1 = _XcmsSquareRoot((a1 * bi)); + if (a1 == b1) + break; + d = XCMS_FABS(a1 - b1); + if (d < maxerror) + break; + ai = a1; + bi = b1; + } + + l = ((a1 > b1) ? b1 : a1); + + a1 = _XcmsSquareRoot(1 + (x * x)); + return (x / (a1 * l)); +} diff --git a/src/xcms/uvY.c b/src/xcms/uvY.c new file mode 100644 index 00000000..3438d88d --- /dev/null +++ b/src/xcms/uvY.c @@ -0,0 +1,409 @@ +/* $Xorg: uvY.c,v 1.3 2000/08/17 19:45:23 cpqbld Exp $ */ + +/* + * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. + * All Rights Reserved + * + * This file is a component of an X Window System-specific implementation + * of XCMS based on the TekColor Color Management System. Permission is + * hereby granted to use, copy, modify, sell, and otherwise distribute this + * software and its documentation for any purpose and without fee, provided + * that this copyright, permission, and disclaimer notice is reproduced in + * all copies of this software and in supporting documentation. TekColor + * is a trademark of Tektronix, Inc. + * + * Tektronix makes no representation about the suitability of this software + * for any purpose. It is provided "as is" and with all faults. + * + * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, + * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX 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 THE PERFORMANCE OF THIS SOFTWARE. + * + * + * NAME + * CIEuvy.c + * + * DESCRIPTION + * This file contains routines that support the CIE u'v'Y + * color space to include conversions to and from the CIE + * XYZ space. + * + * DOCUMENTATION + * "TekColor Color Management System, System Implementor's Manual" + */ + +#include <X11/Xos.h> +#include "Xlibint.h" +#include "Xcmsint.h" + + +/* + * EXTERNS + */ +extern char _XcmsCIEuvY_prefix[]; + + +/* + * FORWARD DECLARATIONS + */ + +static int CIEuvY_ParseString(); +Status _XcmsCIEuvY_ValidSpec(); +/* + * DEFINES + * Internal definitions that need NOT be exported to any package + * or program using this package. + */ +#ifdef DBL_EPSILON +# define XMY_DBL_EPSILON DBL_EPSILON +#else +# define XMY_DBL_EPSILON 0.00001 +#endif + + +/* + * LOCAL VARIABLES + */ + + /* + * NULL terminated list of functions applied to get from CIEuvY to CIEXYZ + */ +static XcmsConversionProc Fl_CIEuvY_to_CIEXYZ[] = { + XcmsCIEuvYToCIEXYZ, + NULL +}; + + /* + * NULL terminated list of functions applied to get from CIEXYZ to CIEuvY + */ +static XcmsConversionProc Fl_CIEXYZ_to_CIEuvY[] = { + XcmsCIEXYZToCIEuvY, + NULL +}; + + +/* + * GLOBALS + */ + + /* + * CIE uvY Color Space + */ +XcmsColorSpace XcmsCIEuvYColorSpace = + { + _XcmsCIEuvY_prefix, /* prefix */ + XcmsCIEuvYFormat, /* id */ + CIEuvY_ParseString, /* parseString */ + Fl_CIEuvY_to_CIEXYZ, /* to_CIEXYZ */ + Fl_CIEXYZ_to_CIEuvY, /* from_CIEXYZ */ + 1 + }; + + + +/************************************************************************ + * * + * PRIVATE ROUTINES * + * * + ************************************************************************/ + +/* + * NAME + * CIEuvY_ParseString + * + * SYNOPSIS + */ +static int +CIEuvY_ParseString(spec, pColor) + register char *spec; + XcmsColor *pColor; +/* + * DESCRIPTION + * This routines takes a string and attempts to convert + * it into a XcmsColor structure with XcmsCIEuvYFormat. + * The assumed CIEuvY string syntax is: + * CIEuvY:<u>/<v>/<Y> + * Where u, v, and Y are in string input format for floats + * consisting of: + * a. an optional sign + * b. a string of numbers possibly containing a decimal point, + * c. an optional exponent field containing an 'E' or 'e' + * followed by a possibly signed integer string. + * + * RETURNS + * 0 if failed, non-zero otherwise. + */ +{ + int n; + char *pchar; + + if ((pchar = strchr(spec, ':')) == NULL) { + return(XcmsFailure); + } + n = (int)(pchar - spec); + + /* + * Check for proper prefix. + */ + if (strncmp(spec, _XcmsCIEuvY_prefix, n) != 0) { + return(XcmsFailure); + } + + /* + * Attempt to parse the value portion. + */ + if (sscanf(spec + n + 1, "%lf/%lf/%lf", + &pColor->spec.CIEuvY.u_prime, + &pColor->spec.CIEuvY.v_prime, + &pColor->spec.CIEuvY.Y) != 3) { + return(XcmsFailure); + } + pColor->format = XcmsCIEuvYFormat; + pColor->pixel = 0; + return(_XcmsCIEuvY_ValidSpec(pColor)); +} + + +/************************************************************************ + * * + * PUBLIC ROUTINES * + * * + ************************************************************************/ + +/* + * NAME + * XcmsCIEuvY_ValidSpec + * + * SYNOPSIS + */ +Status +_XcmsCIEuvY_ValidSpec(pColor) + XcmsColor *pColor; +/* + * DESCRIPTION + * Checks if color specification valid for CIE u'v'Y. + * + * RETURNS + * XcmsFailure if invalid, + * XcmsSuccess if valid. + * + */ +{ + if (pColor->format != XcmsCIEuvYFormat + || + (pColor->spec.CIEuvY.Y < 0.0 - XMY_DBL_EPSILON) + || + (pColor->spec.CIEuvY.Y > 1.0 + XMY_DBL_EPSILON)) { + return(XcmsFailure); + } + return(XcmsSuccess); +} + + +/* + * NAME + * XcmsCIEuvYToCIEXYZ - convert CIEuvY to CIEXYZ + * + * SYNOPSIS + */ +Status +XcmsCIEuvYToCIEXYZ(ccc, puvY_WhitePt, pColors_in_out, nColors) + XcmsCCC ccc; + XcmsColor *puvY_WhitePt; + XcmsColor *pColors_in_out; + unsigned int nColors; +/* + * DESCRIPTION + * Converts color specifications in an array of XcmsColor + * structures from CIEuvY format to CIEXYZ format. + * + * RETURNS + * XcmsFailure if failed, + * XcmsSuccess if succeeded. + * + */ +{ + XcmsCIEXYZ XYZ_return; + XcmsColor whitePt; + int i; + XcmsColor *pColor = pColors_in_out; + XcmsFloat div, x, y, z, Y; + + /* + * Check arguments + * Postpone checking puvY_WhitePt until it is actually needed + * otherwise converting between XYZ and uvY will fail. + */ + if (pColors_in_out == NULL) { + return(XcmsFailure); + } + + + /* + * Now convert each XcmsColor structure to CIEXYZ form + */ + for (i = 0; i < nColors; i++, pColor++) { + + /* Make sure original format is CIEuvY */ + if (!_XcmsCIEuvY_ValidSpec(pColor)) { + return(XcmsFailure); + } + + /* + * Convert to CIEXYZ + */ + + Y = pColor->spec.CIEuvY.Y; + + /* Convert color u'v' to xyz space */ + div = (6.0 * pColor->spec.CIEuvY.u_prime) - (16.0 * pColor->spec.CIEuvY.v_prime) + 12.0; + if (div == 0.0) { + /* use white point since div == 0 */ + if (puvY_WhitePt == NULL ) { + return(XcmsFailure); + } + /* + * Make sure white point is in CIEuvY form + */ + if (puvY_WhitePt->format != XcmsCIEuvYFormat) { + /* Make copy of the white point because we're going to modify it */ + memcpy((char *)&whitePt, (char *)puvY_WhitePt, sizeof(XcmsColor)); + if (!_XcmsDIConvertColors(ccc, &whitePt, (XcmsColor *)NULL, 1, + XcmsCIEuvYFormat)) { + return(XcmsFailure); + } + puvY_WhitePt = &whitePt; + } + /* Make sure it is a white point, i.e., Y == 1.0 */ + if (puvY_WhitePt->spec.CIEuvY.Y != 1.0) { + return(XcmsFailure); + } + div = (6.0 * puvY_WhitePt->spec.CIEuvY.u_prime) - + (16.0 * puvY_WhitePt->spec.CIEuvY.v_prime) + 12.0; + if (div == 0) { + /* internal error */ + return(XcmsFailure); + } + x = 9.0 * puvY_WhitePt->spec.CIEuvY.u_prime / div; + y = 4.0 * puvY_WhitePt->spec.CIEuvY.v_prime / div; + } else { + x = 9.0 * pColor->spec.CIEuvY.u_prime / div; + y = 4.0 * pColor->spec.CIEuvY.v_prime / div; + } + z = 1.0 - x - y; + + /* Convert from xyz to XYZ */ + /* Conversion uses color normalized lightness based on Y */ + if (y != 0.0) { + XYZ_return.X = x * Y / y; + } else { + XYZ_return.X = x; + } + XYZ_return.Y = Y; + if (y != 0.0) { + XYZ_return.Z = z * Y / y; + } else { + XYZ_return.Z = z; + } + + memcpy((char *)&pColor->spec.CIEXYZ, (char *)&XYZ_return, sizeof(XcmsCIEXYZ)); + /* Identify that format is now CIEXYZ */ + pColor->format = XcmsCIEXYZFormat; + } + + return(XcmsSuccess); +} + + +/* + * NAME + * XcmsCIEXYZToCIEuvY - convert CIEXYZ to CIEuvY + * + * SYNOPSIS + */ +Status +XcmsCIEXYZToCIEuvY(ccc, puvY_WhitePt, pColors_in_out, nColors) + XcmsCCC ccc; + XcmsColor *puvY_WhitePt; + XcmsColor *pColors_in_out; + unsigned int nColors; +/* + * DESCRIPTION + * Converts color specifications in an array of XcmsColor + * structures from CIEXYZ format to CIEuvY format. + * + * RETURNS + * XcmsFailure if failed, + * XcmsSuccess if succeeded. + * + */ +{ + XcmsCIEuvY uvY_return; + XcmsColor whitePt; + int i; + XcmsColor *pColor = pColors_in_out; + XcmsFloat div; + + /* + * Check arguments + * Postpone checking puvY_WhitePt until it is actually needed + * otherwise converting between XYZ and uvY will fail. + */ + if (pColors_in_out == NULL) { + return(XcmsFailure); + } + + /* + * Now convert each XcmsColor structure to CIEuvY form + */ + for (i = 0; i < nColors; i++, pColor++) { + + /* Make sure original format is CIEXYZ */ + if (!_XcmsCIEXYZ_ValidSpec(pColor)) { + return(XcmsFailure); + } + + /* Convert to CIEuvY */ + div = pColor->spec.CIEXYZ.X + (15.0 * pColor->spec.CIEXYZ.Y) + + (3.0 * pColor->spec.CIEXYZ.Z); + if (div == 0.0) { + /* Use white point since div == 0.0 */ + if (puvY_WhitePt == NULL ) { + return(XcmsFailure); + } + /* + * Make sure white point is in CIEuvY form + */ + if (puvY_WhitePt->format != XcmsCIEuvYFormat) { + /* Make copy of the white point because we're going to modify it */ + memcpy((char *)&whitePt, (char *)puvY_WhitePt, sizeof(XcmsColor)); + if (!_XcmsDIConvertColors(ccc, &whitePt, (XcmsColor *)NULL, 1, + XcmsCIEuvYFormat)) { + return(XcmsFailure); + } + puvY_WhitePt = &whitePt; + } + /* Make sure it is a white point, i.e., Y == 1.0 */ + if (puvY_WhitePt->spec.CIEuvY.Y != 1.0) { + return(XcmsFailure); + } + uvY_return.Y = pColor->spec.CIEXYZ.Y; + uvY_return.u_prime = puvY_WhitePt->spec.CIEuvY.u_prime; + uvY_return.v_prime = puvY_WhitePt->spec.CIEuvY.v_prime; + } else { + uvY_return.u_prime = 4.0 * pColor->spec.CIEXYZ.X / div; + uvY_return.v_prime = 9.0 * pColor->spec.CIEXYZ.Y / div; + uvY_return.Y = pColor->spec.CIEXYZ.Y; + } + + memcpy((char *)&pColor->spec.CIEuvY, (char *)&uvY_return, sizeof(XcmsCIEuvY)); + /* Identify that format is now CIEuvY */ + pColor->format = XcmsCIEuvYFormat; + } + + return(XcmsSuccess); +} diff --git a/src/xcms/xyY.c b/src/xcms/xyY.c new file mode 100644 index 00000000..00bd8413 --- /dev/null +++ b/src/xcms/xyY.c @@ -0,0 +1,381 @@ +/* $Xorg: xyY.c,v 1.3 2000/08/17 19:45:23 cpqbld Exp $ */ + +/* + * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. + * All Rights Reserved + * + * This file is a component of an X Window System-specific implementation + * of Xcms based on the TekColor Color Management System. Permission is + * hereby granted to use, copy, modify, sell, and otherwise distribute this + * software and its documentation for any purpose and without fee, provided + * that this copyright, permission, and disclaimer notice is reproduced in + * all copies of this software and in supporting documentation. TekColor + * is a trademark of Tektronix, Inc. + * + * Tektronix makes no representation about the suitability of this software + * for any purpose. It is provided "as is" and with all faults. + * + * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, + * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX 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 THE PERFORMANCE OF THIS SOFTWARE. + * + * NAME + * CIExyY.c + * + * DESCRIPTION + * This file contains routines that support the CIE xyY + * color space to include conversions to and from the CIE + * XYZ space. + * + * DOCUMENTATION + * "TekColor Color Management System, System Implementor's Manual" + */ + +#include <stdio.h> +#include <X11/Xos.h> +#include "Xlibint.h" +#include "Xcmsint.h" + +/* + * DEFINES + */ +#define EPS 0.00001 /* some extremely small number */ +#ifdef DBL_EPSILON +# define XMY_DBL_EPSILON DBL_EPSILON +#else +# define XMY_DBL_EPSILON 0.00001 +#endif + +/* + * EXTERNS + */ + +extern char _XcmsCIExyY_prefix[]; + +/* + * FORWARD DECLARATIONS + */ + +static int CIExyY_ParseString(); +static Status XcmsCIExyY_ValidSpec(); + + +/* + * LOCAL VARIABLES + */ + + /* + * NULL terminated list of functions applied to get from CIExyY to CIEXYZ + */ +static XcmsConversionProc Fl_CIExyY_to_CIEXYZ[] = { + XcmsCIExyYToCIEXYZ, + NULL +}; + + /* + * NULL terminated list of functions applied to get from CIEXYZ to CIExyY + */ +static XcmsConversionProc Fl_CIEXYZ_to_CIExyY[] = { + XcmsCIEXYZToCIExyY, + NULL +}; + + +/* + * GLOBALS + */ + + /* + * CIE xyY Color Space + */ +XcmsColorSpace XcmsCIExyYColorSpace = + { + _XcmsCIExyY_prefix, /* prefix */ + XcmsCIExyYFormat, /* id */ + CIExyY_ParseString, /* parseString */ + Fl_CIExyY_to_CIEXYZ, /* to_CIEXYZ */ + Fl_CIEXYZ_to_CIExyY, /* from_CIEXYZ */ + 1 + }; + + + +/************************************************************************ + * * + * PRIVATE ROUTINES * + * * + ************************************************************************/ + +/* + * NAME + * CIExyY_ParseString + * + * SYNOPSIS + */ +static int +CIExyY_ParseString(spec, pColor) + register char *spec; + XcmsColor *pColor; +/* + * DESCRIPTION + * This routines takes a string and attempts to convert + * it into a XcmsColor structure with XcmsCIExyYFormat. + * The assumed CIExyY string syntax is: + * CIExyY:<x>/<y>/<Y> + * Where x, y, and Y are in string input format for floats + * consisting of: + * a. an optional sign + * b. a string of numbers possibly containing a decimal point, + * c. an optional exponent field containing an 'E' or 'e' + * followed by a possibly signed integer string. + * + * RETURNS + * 0 if failed, non-zero otherwise. + */ +{ + int n; + char *pchar; + + if ((pchar = strchr(spec, ':')) == NULL) { + return(XcmsFailure); + } + n = (int)(pchar - spec); + + /* + * Check for proper prefix. + */ + if (strncmp(spec, _XcmsCIExyY_prefix, n) != 0) { + return(XcmsFailure); + } + + /* + * Attempt to parse the value portion. + */ + if (sscanf(spec + n + 1, "%lf/%lf/%lf", + &pColor->spec.CIExyY.x, + &pColor->spec.CIExyY.y, + &pColor->spec.CIExyY.Y) != 3) { + return(XcmsFailure); + } + pColor->format = XcmsCIExyYFormat; + pColor->pixel = 0; + return(XcmsCIExyY_ValidSpec(pColor)); +} + + + +/************************************************************************ + * * + * PUBLIC ROUTINES * + * * + ************************************************************************/ + +/* + * NAME + * CIExyY_ValidSpec() + * + * SYNOPSIS + */ +static Status +XcmsCIExyY_ValidSpec(pColor) + XcmsColor *pColor; +/* + * DESCRIPTION + * Checks a valid CIExyY color specification. + * + * RETURNS + * XcmsFailure if invalid. + * XcmsSuccess if valid. + * + */ +{ + if (pColor->format != XcmsCIExyYFormat + || + (pColor->spec.CIExyY.x < 0.0 - XMY_DBL_EPSILON) + || + (pColor->spec.CIExyY.x > 1.0 + XMY_DBL_EPSILON) + || + (pColor->spec.CIExyY.y < 0.0 - XMY_DBL_EPSILON) + || + (pColor->spec.CIExyY.y > 1.0 + XMY_DBL_EPSILON) + || + (pColor->spec.CIExyY.Y < 0.0 - XMY_DBL_EPSILON) + || + (pColor->spec.CIExyY.Y > 1.0 + XMY_DBL_EPSILON)) { + return(XcmsFailure); + } + return(XcmsSuccess); +} + + +/* + * NAME + * XcmsCIExyYToCIEXYZ - convert CIExyY to CIEXYZ + * + * SYNOPSIS + */ +Status +XcmsCIExyYToCIEXYZ(ccc, pxyY_WhitePt, pColors_in_out, nColors) + XcmsCCC ccc; + XcmsColor *pxyY_WhitePt; + XcmsColor *pColors_in_out; + unsigned int nColors; +/* + * DESCRIPTION + * Converts color specifications in an array of XcmsColor + * structures from CIExyY format to CIEXYZ format. + * + * RETURNS + * XcmsFailure if failed, + * XcmsSuccess if succeeded. + */ +{ + XcmsColor *pColor = pColors_in_out; + XcmsColor whitePt; + XcmsCIEXYZ XYZ_return; + XcmsFloat div; /* temporary storage in case divisor is zero */ + XcmsFloat u, v, x, y, z; /* temporary storage */ + register int i; + + /* + * Check arguments + */ + if (pxyY_WhitePt == NULL || pColors_in_out == NULL) { + return(XcmsFailure); + } + + + /* + * Now convert each XcmsColor structure to CIEXYZ form + */ + for (i = 0; i < nColors; i++, pColor++) { + /* Make sure original format is CIExyY and valid */ + if (!XcmsCIExyY_ValidSpec(pColor)) { + return(XcmsFailure); + } + + if ((div = (-2 * pColor->spec.CIExyY.x) + (12 * pColor->spec.CIExyY.y) + 3) == 0.0) { + /* Note that the divisor is zero */ + /* This return is abitrary. */ + XYZ_return.X = 0; + XYZ_return.Y = 0; + XYZ_return.Z = 0; + } else { + /* + * Make sure white point is in CIEXYZ form + */ + if (pxyY_WhitePt->format != XcmsCIEXYZFormat) { + /* Make copy of the white point because we're going to modify it */ + memcpy((char *)&whitePt, (char *)pxyY_WhitePt, sizeof(XcmsColor)); + if (!_XcmsDIConvertColors(ccc, &whitePt, (XcmsColor *)NULL, 1, + XcmsCIEXYZFormat)) { + return(XcmsFailure); + } + pxyY_WhitePt = &whitePt; + } + + /* Make sure it is a white point, i.e., Y == 1.0 */ + if (pxyY_WhitePt->spec.CIEXYZ.Y != 1.0) { + return(XcmsFailure); + } + + /* Convert from xyY to uvY to XYZ */ + u = (4 * pColor->spec.CIExyY.x) / div; + v = (9 * pColor->spec.CIExyY.y) / div; + div = (6.0 * u) - (16.0 * v) + 12.0; + if (div == 0.0) { + /* Note that the divisor is zero */ + /* This return is abitrary. */ + if ((div = (6.0 * whitePt.spec.CIEuvY.u_prime) - + (16.0 * whitePt.spec.CIEuvY.v_prime) + 12.0) == 0.0) { + div = EPS; + } + x = 9.0 * whitePt.spec.CIEuvY.u_prime / div; + y = 4.0 * whitePt.spec.CIEuvY.u_prime / div; + } else { + /* convert u, v to small xyz */ + x = 9.0 * u / div; + y = 4.0 * v / div; + } + z = 1.0 - x - y; + if (y == 0.0) y = EPS; /* Have to worry about divide by 0 */ + XYZ_return.Y = pColor->spec.CIExyY.Y; + XYZ_return.X = x * XYZ_return.Y / y; + XYZ_return.Z = z * XYZ_return.Y / y; + } + + /* Copy result to pColor */ + memcpy ((char *)&pColor->spec, (char *)&XYZ_return, sizeof(XcmsCIEXYZ)); + + /* Identify that the format is now CIEXYZ */ + pColor->format = XcmsCIEXYZFormat; + } + return(XcmsSuccess); +} + + +/* + * NAME + * XcmsCIEXYZToCIExyY - convert CIEXYZ to CIExyY + * + * SYNOPSIS + */ +/* ARGSUSED */ +Status +XcmsCIEXYZToCIExyY(ccc, pxyY_WhitePt, pColors_in_out, nColors) + XcmsCCC ccc; + XcmsColor *pxyY_WhitePt; + XcmsColor *pColors_in_out; + unsigned int nColors; +/* + * DESCRIPTION + * Converts color specifications in an array of XcmsColor + * structures from CIEXYZ format to CIExyY format. + * + * RETURNS + * XcmsFailure if failed, + * XcmsSuccess if succeeded. + * + */ +{ + XcmsColor *pColor = pColors_in_out; + XcmsCIExyY xyY_return; + XcmsFloat div; /* temporary storage in case divisor is zero */ + register int i; + + /* + * Check arguments + * pxyY_WhitePt ignored + */ + if (pColors_in_out == NULL) { + return(XcmsFailure); + } + + /* + * Now convert each XcmsColor structure to CIEXYZ form + */ + for (i = 0; i < nColors; i++, pColor++) { + + if (!_XcmsCIEXYZ_ValidSpec(pColor)) { + return(XcmsFailure); + } + /* Now convert for XYZ to xyY */ + if ((div = pColor->spec.CIEXYZ.X + pColor->spec.CIEXYZ.Y + pColor->spec.CIEXYZ.Z) == 0.0) { + div = EPS; + } + xyY_return.x = pColor->spec.CIEXYZ.X / div; + xyY_return.y = pColor->spec.CIEXYZ.Y / div; + xyY_return.Y = pColor->spec.CIEXYZ.Y; + + /* Copy result to pColor */ + memcpy ((char *)&pColor->spec, (char *)&xyY_return, sizeof(XcmsCIExyY)); + + /* Identify that the format is now CIEXYZ */ + pColor->format = XcmsCIExyYFormat; + } + return(XcmsSuccess); +} diff --git a/src/xkb/XKB.c b/src/xkb/XKB.c new file mode 100644 index 00000000..22a8731f --- /dev/null +++ b/src/xkb/XKB.c @@ -0,0 +1,926 @@ +/* $Xorg: XKB.c,v 1.3 2000/08/17 19:44:59 cpqbld Exp $ */ +/************************************************************ +Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc. + +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 Silicon Graphics not be +used in advertising or publicity pertaining to distribution +of the software without specific prior written permission. +Silicon Graphics makes no representation about the suitability +of this software for any purpose. It is provided "as is" +without any express or implied warranty. + +SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS +SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON +GRAPHICS 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. + +********************************************************/ + +#include <stdio.h> +#define NEED_REPLIES +#define NEED_EVENTS +#include "Xlibint.h" +#include <X11/extensions/XKBproto.h> +#include "XKBlibint.h" + +XkbInternAtomFunc _XkbInternAtomFunc= XInternAtom; +XkbGetAtomNameFunc _XkbGetAtomNameFunc= XGetAtomName; + +Bool +#if NeedFunctionPrototypes +XkbQueryExtension( Display *dpy, + int * opcodeReturn, + int * eventBaseReturn, + int * errorBaseReturn, + int * majorReturn, + int * minorReturn) +#else +XkbQueryExtension(dpy,opcodeReturn,eventBaseReturn,errorBaseReturn, + majorReturn,minorReturn) + Display *dpy; + int *opcodeReturn; + int *eventBaseReturn; + int *errorBaseReturn; + int *majorReturn; + int *minorReturn; +#endif +{ + if (!XkbUseExtension(dpy,majorReturn,minorReturn)) + return False; + if (opcodeReturn) + *opcodeReturn = dpy->xkb_info->codes->major_opcode; + if (eventBaseReturn) + *eventBaseReturn = dpy->xkb_info->codes->first_event; + if (errorBaseReturn) + *errorBaseReturn = dpy->xkb_info->codes->first_error; + if (majorReturn) + *majorReturn = dpy->xkb_info->srv_major; + if (minorReturn) + *minorReturn = dpy->xkb_info->srv_minor; + return True; +} + +Bool +#if NeedFunctionPrototypes +XkbLibraryVersion(int *libMajorRtrn,int *libMinorRtrn) +#else +XkbLibraryVersion(libMajorRtrn,libMinorRtrn) + int *libMajorRtrn; + int *libMinorRtrn; +#endif +{ +int supported; + + if (*libMajorRtrn != XkbMajorVersion) { + /* version 0.65 is (almost) compatible with 1.00 */ + if ((XkbMajorVersion==1)&&(((*libMajorRtrn)==0)&&((*libMinorRtrn)==65))) + supported= True; + else supported= False; + } + else { + supported = True; + } + + *libMajorRtrn = XkbMajorVersion; + *libMinorRtrn = XkbMinorVersion; + return supported; +} + +Bool +#if NeedFunctionPrototypes +XkbSelectEvents( Display * dpy, + unsigned int deviceSpec, + unsigned int affect, + unsigned int selectAll) +#else +XkbSelectEvents(dpy,deviceSpec,affect,selectAll) + Display *dpy; + unsigned int deviceSpec; + unsigned int affect; + unsigned int selectAll; +#endif +{ + register xkbSelectEventsReq *req; + XkbInfoPtr xkbi; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) + return False; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + xkbi->selected_events&= ~affect; + xkbi->selected_events|= (affect&selectAll); + GetReq(kbSelectEvents, req); + req->reqType = xkbi->codes->major_opcode; + req->xkbReqType = X_kbSelectEvents; + req->deviceSpec = deviceSpec; + req->affectWhich = (CARD16)affect; + req->clear = affect&(~selectAll); + req->selectAll = affect&selectAll; + if (affect&XkbMapNotifyMask) { + req->affectMap= XkbAllMapComponentsMask; + /* the implicit support needs the client info */ + /* even if the client itself doesn't want it */ + if (selectAll&XkbMapNotifyMask) + req->map= XkbAllMapEventsMask; + else req->map= XkbAllClientInfoMask; + if (selectAll&XkbMapNotifyMask) + xkbi->selected_map_details= XkbAllMapEventsMask; + else xkbi->selected_map_details= 0; + } + if (affect&XkbNewKeyboardNotifyMask) { + if (selectAll&XkbNewKeyboardNotifyMask) + xkbi->selected_nkn_details= XkbAllNewKeyboardEventsMask; + else xkbi->selected_nkn_details= 0; + if (!(xkbi->xlib_ctrls&XkbLC_IgnoreNewKeyboards)) { + /* we want it, even if the client doesn't. Don't mess */ + /* around with details -- ask for all of them and throw */ + /* away the ones we don't need */ + req->selectAll|= XkbNewKeyboardNotifyMask; + } + } + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + +Bool +#if NeedFunctionPrototypes +XkbSelectEventDetails( Display * dpy, + unsigned deviceSpec, + unsigned eventType, + unsigned long int affect, + unsigned long int details) +#else +XkbSelectEventDetails(dpy,deviceSpec,eventType,affect,details) + Display *dpy; + unsigned deviceSpec; + unsigned eventType; + unsigned long int affect; + unsigned long int details; +#endif +{ + register xkbSelectEventsReq *req; + XkbInfoPtr xkbi; + int size; + char *out; + union { + CARD8 *c8; + CARD16 *c16; + CARD32 *c32; + } u; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) + return False; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + if (affect&details) xkbi->selected_events|= (1<<eventType); + else xkbi->selected_events&= ~(1<<eventType); + GetReq(kbSelectEvents, req); + req->reqType = xkbi->codes->major_opcode; + req->xkbReqType = X_kbSelectEvents; + req->deviceSpec = deviceSpec; + req->clear= req->selectAll= 0; + if (eventType==XkbMapNotify) { + /* we need all of the client info, even if the application */ + /* doesn't. Make sure that we always request the stuff */ + /* that the implicit support needs, and just filter out anything */ + /* the client doesn't want later */ + req->affectWhich = 0; + req->selectAll = 0; + req->clear = 0; + req->affectMap = (CARD16)affect; + req->map = (CARD16)details|(XkbAllClientInfoMask&affect); + req->affectWhich = XkbMapNotifyMask; + xkbi->selected_map_details&= ~affect; + xkbi->selected_map_details|= (details&affect); + } + else { + req->affectMap = req->map = 0; + req->affectWhich= (1<<eventType); + switch (eventType) { + case XkbNewKeyboardNotify: + xkbi->selected_nkn_details&= ~affect; + xkbi->selected_nkn_details|= (details&affect); + if (!(xkbi->xlib_ctrls&XkbLC_IgnoreNewKeyboards)) + details= (affect&XkbAllNewKeyboardEventsMask); + case XkbStateNotify: + case XkbNamesNotify: + case XkbAccessXNotify: + case XkbExtensionDeviceNotify: + size= 2; + req->length+= 1; + break; + case XkbControlsNotify: + case XkbIndicatorStateNotify: + case XkbIndicatorMapNotify: + size= 4; + req->length+= 2; + break; + case XkbBellNotify: + case XkbActionMessage: + case XkbCompatMapNotify: + size= 1; + req->length+= 1; + break; + } + BufAlloc(char *,out,(((size*2)+(unsigned)3)/4)*4); + u.c8= (CARD8 *)out; + if (size==2) { + u.c16[0]= (CARD16)affect; + u.c16[1]= (CARD16)details; + } + else if (size==4) { + u.c32[0]= (CARD32)affect; + u.c32[1]= (CARD32)details; + } + else { + u.c8[0]= (CARD8)affect; + u.c8[1]= (CARD8)details; + } + } + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + +Bool +#if NeedFunctionPrototypes +XkbLockModifiers( Display * dpy, + unsigned int deviceSpec, + unsigned int affect, + unsigned int values) +#else +XkbLockModifiers(dpy,deviceSpec,affect,values) + Display *dpy; + unsigned int deviceSpec; + unsigned int affect; + unsigned int values; +#endif +{ + register xkbLatchLockStateReq *req; + XkbInfoPtr xkbi; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) + return False; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbLatchLockState, req); + req->reqType = xkbi->codes->major_opcode; + req->xkbReqType = X_kbLatchLockState; + req->deviceSpec = deviceSpec; + req->affectModLocks= affect; + req->modLocks = values; + req->lockGroup = False; + req->groupLock = 0; + + req->affectModLatches = req->modLatches = 0; + req->latchGroup = False; + req->groupLatch = 0; + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + +Bool +#if NeedFunctionPrototypes +XkbLatchModifiers( Display * dpy, + unsigned int deviceSpec, + unsigned int affect, + unsigned int values) +#else +XkbLatchModifiers(dpy,deviceSpec,affect,values) + Display *dpy; + unsigned int deviceSpec; + unsigned int affect; + unsigned int values; +#endif +{ + register xkbLatchLockStateReq *req; + XkbInfoPtr xkbi; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) + return False; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbLatchLockState, req); + req->reqType = xkbi->codes->major_opcode; + req->xkbReqType = X_kbLatchLockState; + req->deviceSpec = deviceSpec; + + req->affectModLatches= affect; + req->modLatches = values; + req->latchGroup = False; + req->groupLatch = 0; + + req->affectModLocks = req->modLocks = 0; + req->lockGroup = False; + req->groupLock = 0; + + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + +Bool +#if NeedFunctionPrototypes +XkbLockGroup(Display *dpy,unsigned int deviceSpec,unsigned int group) +#else +XkbLockGroup(dpy,deviceSpec,group) + Display *dpy; + unsigned int deviceSpec; + unsigned int group; +#endif +{ + register xkbLatchLockStateReq *req; + XkbInfoPtr xkbi; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) + return False; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbLatchLockState, req); + req->reqType = xkbi->codes->major_opcode; + req->xkbReqType = X_kbLatchLockState; + req->deviceSpec = deviceSpec; + req->affectModLocks= 0; + req->modLocks = 0; + req->lockGroup = True; + req->groupLock = group; + + req->affectModLatches = req->modLatches = 0; + req->latchGroup = False; + req->groupLatch = 0; + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + +Bool +#if NeedFunctionPrototypes +XkbLatchGroup(Display *dpy,unsigned int deviceSpec,unsigned int group) +#else +XkbLatchGroup(dpy,deviceSpec,group) + Display *dpy; + unsigned int deviceSpec; + unsigned int group; +#endif +{ + register xkbLatchLockStateReq *req; + XkbInfoPtr xkbi; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) + return False; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbLatchLockState, req); + req->reqType = xkbi->codes->major_opcode; + req->xkbReqType = X_kbLatchLockState; + req->deviceSpec = deviceSpec; + + req->affectModLatches= 0; + req->modLatches = 0; + req->latchGroup = True; + req->groupLatch = group; + + req->affectModLocks = req->modLocks = 0; + req->lockGroup = False; + req->groupLock = 0; + + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + +unsigned +#if NeedFunctionPrototypes +XkbSetXlibControls(Display *dpy,unsigned affect,unsigned values) +#else +XkbSetXlibControls(dpy,affect,values) + Display * dpy; + unsigned affect; + unsigned values; +#endif +{ + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) + return False; + affect&= XkbLC_AllControls; + dpy->xkb_info->xlib_ctrls&= ~affect; + dpy->xkb_info->xlib_ctrls|= (affect&values); + return dpy->xkb_info->xlib_ctrls; +} + +unsigned +#if NeedFunctionPrototypes +XkbGetXlibControls(Display *dpy) +#else +XkbGetXlibControls(dpy) + Display * dpy; +#endif +{ + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) + return 0; + return dpy->xkb_info->xlib_ctrls; +} + +unsigned int +#if NeedFunctionPrototypes +XkbXlibControlsImplemented(void) +#else +XkbXlibControlsImplemented() +#endif +{ +#ifdef __sgi + return XkbLC_AllControls; +#else + return XkbLC_AllControls&~XkbLC_AllComposeControls; +#endif +} + +Bool +#if NeedFunctionPrototypes +XkbSetDebuggingFlags( Display * dpy, + unsigned int mask, + unsigned int flags, + char * msg, + unsigned int ctrls_mask, + unsigned int ctrls, + unsigned int * rtrn_flags, + unsigned int * rtrn_ctrls) +#else +XkbSetDebuggingFlags(dpy,mask,flags,msg,ctrls_mask,ctrls,rtrn_flags,rtrn_ctrls) + Display * dpy; + unsigned int mask; + unsigned int flags; + char * msg; + unsigned int ctrls_mask; + unsigned int ctrls; + unsigned int * rtrn_flags; + unsigned int * rtrn_ctrls; +#endif +{ + register xkbSetDebuggingFlagsReq *req; + xkbSetDebuggingFlagsReply rep; + XkbInfoPtr xkbi; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) + return False; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbSetDebuggingFlags, req); + req->reqType= xkbi->codes->major_opcode; + req->xkbReqType= X_kbSetDebuggingFlags; + req->affectFlags= mask; + req->flags= flags; + req->affectCtrls= ctrls_mask; + req->ctrls= ctrls; + + if (msg) { + char *out; + req->msgLength= (unsigned short)strlen(msg)+1; + req->length+= (req->msgLength+(unsigned)3)>>2; + BufAlloc(char *,out,((req->msgLength+(unsigned)3)/4)*4); + memcpy(out,msg,req->msgLength); + } + else req->msgLength= 0; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + if (rtrn_flags) + *rtrn_flags= rep.currentFlags; + if (rtrn_ctrls) + *rtrn_ctrls= rep.currentCtrls; + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + +Bool +#if NeedFunctionPrototypes +XkbComputeEffectiveMap( XkbDescPtr xkb, + XkbKeyTypePtr type, + unsigned char * map_rtrn) +#else +XkbComputeEffectiveMap(xkb,type,map_rtrn) + XkbDescPtr xkb; + XkbKeyTypePtr type; + unsigned char * map_rtrn; +#endif +{ +register int i; +unsigned tmp; +XkbKTMapEntryPtr entry; + + if ((!xkb)||(!type)||(!xkb->server)) + return False; + + if (type->mods.vmods!=0) { + if (!XkbVirtualModsToReal(xkb,type->mods.vmods,&tmp)) + return False; + + type->mods.mask= tmp|type->mods.real_mods; + entry= type->map; + for (i=0;i<type->map_count;i++,entry++) { + tmp= 0; + if (entry->mods.vmods!=0) { + if (!XkbVirtualModsToReal(xkb,entry->mods.vmods,&tmp)) + return False; + if (tmp==0) { + entry->active= False; + continue; + } + } + entry->active= True; + entry->mods.mask= (entry->mods.real_mods|tmp)&type->mods.mask; + } + } + else { + type->mods.mask= type->mods.real_mods; + } + if (map_rtrn!=NULL) { + bzero(map_rtrn,type->mods.mask+1); + for (i=0;i<type->map_count;i++) { + if (entry->active) { + map_rtrn[type->map[i].mods.mask]= type->map[i].level; + } + } + } + return True; +} + +Status +#if NeedFunctionPrototypes +XkbGetState(Display *dpy,unsigned deviceSpec,XkbStatePtr rtrn) +#else +XkbGetState(dpy,deviceSpec,rtrn) + Display * dpy; + unsigned deviceSpec; + XkbStatePtr rtrn; +#endif +{ + register xkbGetStateReq *req; + xkbGetStateReply rep; + XkbInfoPtr xkbi; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) + return BadAccess; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbGetState, req); + req->reqType = xkbi->codes->major_opcode; + req->xkbReqType = X_kbGetState; + req->deviceSpec = deviceSpec; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return BadImplementation; + } + rtrn->mods= rep.mods; + rtrn->base_mods= rep.baseMods; + rtrn->latched_mods= rep.latchedMods; + rtrn->locked_mods= rep.lockedMods; + rtrn->group= rep.group; + rtrn->base_group= rep.baseGroup; + rtrn->latched_group= rep.latchedGroup; + rtrn->locked_group= rep.lockedGroup; + rtrn->compat_state= rep.compatState; + rtrn->grab_mods= rep.grabMods; + rtrn->compat_grab_mods= rep.compatGrabMods; + rtrn->lookup_mods= rep.lookupMods; + rtrn->compat_lookup_mods= rep.compatLookupMods; + rtrn->ptr_buttons= rep.ptrBtnState; + UnlockDisplay(dpy); + SyncHandle(); + return Success; +} + +Bool +#if NeedFunctionPrototypes +XkbSetDetectableAutoRepeat(Display *dpy,Bool detectable,Bool *supported) +#else +XkbSetDetectableAutoRepeat(dpy,detectable,supported) + Display * dpy; + Bool detectable; + Bool * supported; +#endif +{ +register xkbPerClientFlagsReq * req; +xkbPerClientFlagsReply rep; +XkbInfoPtr xkbi; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) + return False; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbPerClientFlags, req); + req->reqType = xkbi->codes->major_opcode; + req->xkbReqType = X_kbPerClientFlags; + req->deviceSpec = XkbUseCoreKbd; + req->change = XkbPCF_DetectableAutoRepeatMask; + if (detectable) + req->value = XkbPCF_DetectableAutoRepeatMask; + else req->value = 0; + req->ctrlsToChange = req->autoCtrls= req->autoCtrlValues= 0; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + UnlockDisplay(dpy); + SyncHandle(); + if (supported!=NULL) + *supported= ((rep.supported&XkbPCF_DetectableAutoRepeatMask)!=0); + return ((rep.value&XkbPCF_DetectableAutoRepeatMask)!=0); +} + +Bool +#if NeedFunctionPrototypes +XkbGetDetectableAutoRepeat(Display *dpy,Bool *supported) +#else +XkbGetDetectableAutoRepeat(dpy,supported) + Display * dpy; + Bool * supported; +#endif +{ +register xkbPerClientFlagsReq * req; +xkbPerClientFlagsReply rep; +XkbInfoPtr xkbi; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) + return False; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbPerClientFlags, req); + req->reqType = xkbi->codes->major_opcode; + req->xkbReqType = X_kbPerClientFlags; + req->deviceSpec = XkbUseCoreKbd; + req->change = 0; + req->value = 0; + req->ctrlsToChange = req->autoCtrls= req->autoCtrlValues= 0; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + UnlockDisplay(dpy); + SyncHandle(); + if (supported!=NULL) + *supported= ((rep.supported&XkbPCF_DetectableAutoRepeatMask)!=0); + return ((rep.value&XkbPCF_DetectableAutoRepeatMask)!=0); +} + +Bool +#if NeedFunctionPrototypes +XkbSetAutoResetControls( Display * dpy, + unsigned changes, + unsigned * auto_ctrls, + unsigned * auto_values) +#else +XkbSetAutoResetControls(dpy,changes,auto_ctrls,auto_values) + Display * dpy; + unsigned changes; + unsigned * auto_ctrls; + unsigned * auto_values; +#endif +{ +register xkbPerClientFlagsReq * req; +xkbPerClientFlagsReply rep; +XkbInfoPtr xkbi; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) + return False; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbPerClientFlags, req); + req->reqType = xkbi->codes->major_opcode; + req->xkbReqType = X_kbPerClientFlags; + req->change = XkbPCF_AutoResetControlsMask; + req->deviceSpec = XkbUseCoreKbd; + req->value = XkbPCF_AutoResetControlsMask; + req->ctrlsToChange= changes; + req->autoCtrls= *auto_ctrls; + req->autoCtrlValues= *auto_values; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + UnlockDisplay(dpy); + SyncHandle(); + *auto_ctrls= rep.autoCtrls; + *auto_values= rep.autoCtrlValues; + return ((rep.value&XkbPCF_AutoResetControlsMask)!=0); +} + +Bool +#if NeedFunctionPrototypes +XkbGetAutoResetControls( Display * dpy, + unsigned * auto_ctrls, + unsigned * auto_ctrl_values) +#else +XkbGetAutoResetControls(dpy,auto_ctrls,auto_ctrl_values) + Display * dpy; + unsigned * auto_ctrls; + unsigned * auto_ctrl_values; +#endif +{ +register xkbPerClientFlagsReq * req; +xkbPerClientFlagsReply rep; +XkbInfoPtr xkbi; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) + return False; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbPerClientFlags, req); + req->reqType = xkbi->codes->major_opcode; + req->xkbReqType = X_kbPerClientFlags; + req->deviceSpec = XkbUseCoreKbd; + req->change = 0; + req->value = 0; + req->ctrlsToChange = req->autoCtrls= req->autoCtrlValues= 0; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + UnlockDisplay(dpy); + SyncHandle(); + if (auto_ctrls) + *auto_ctrls= rep.autoCtrls; + if (auto_ctrl_values) + *auto_ctrl_values= rep.autoCtrlValues; + return ((rep.value&XkbPCF_AutoResetControlsMask)!=0); +} + +Bool +#if NeedFunctionPrototypes +XkbSetPerClientControls( Display * dpy, + unsigned change, + unsigned * values) +#else +XkbSetPerClientControls(dpy,change,values) + Display * dpy; + unsigned change; + unsigned * values; +#endif +{ +register xkbPerClientFlagsReq * req; +xkbPerClientFlagsReply rep; +XkbInfoPtr xkbi; +unsigned value_hold = *values; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL)) || + (change & ~(XkbPCF_GrabsUseXKBStateMask|XkbPCF_LookupStateWhenGrabbed|XkbPCF_SendEventUsesXKBState))) + return False; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbPerClientFlags, req); + req->reqType = xkbi->codes->major_opcode; + req->xkbReqType = X_kbPerClientFlags; + req->change = change; + req->deviceSpec = XkbUseCoreKbd; + req->value = *values; + req->ctrlsToChange = req->autoCtrls = req->autoCtrlValues= 0; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + UnlockDisplay(dpy); + SyncHandle(); + *values = rep.value; + return ((rep.value&value_hold)!=0); +} + +Bool +#if NeedFunctionPrototypes +XkbGetPerClientControls( Display * dpy, + unsigned * ctrls) +#else +XkbGetPerClientControls(dpy,ctrls) + Display * dpy; + unsigned * ctrls; +#endif +{ +register xkbPerClientFlagsReq * req; +xkbPerClientFlagsReply rep; +XkbInfoPtr xkbi; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL)) || + (*ctrls & ~(XkbPCF_GrabsUseXKBStateMask|XkbPCF_LookupStateWhenGrabbed|XkbPCF_SendEventUsesXKBState))) + return False; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbPerClientFlags, req); + req->reqType = xkbi->codes->major_opcode; + req->xkbReqType = X_kbPerClientFlags; + req->deviceSpec = XkbUseCoreKbd; + req->change = 0; + req->value = 0; + req->ctrlsToChange = req->autoCtrls= req->autoCtrlValues= 0; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + UnlockDisplay(dpy); + SyncHandle(); + if (ctrls) + *ctrls= (rep.value&XkbPCF_GrabsUseXKBStateMask|XkbPCF_LookupStateWhenGrabbed|XkbPCF_SendEventUsesXKBState); + return (True); +} + +Display * +#if NeedFunctionPrototypes +XkbOpenDisplay( char * name, + int * ev_rtrn, + int * err_rtrn, + int * major_rtrn, + int * minor_rtrn, + int * reason) +#else +XkbOpenDisplay(name,ev_rtrn,err_rtrn,major_rtrn,minor_rtrn,reason) + char * name; + int * ev_rtrn; + int * err_rtrn; + int * major_rtrn; + int * minor_rtrn; + int * reason; +#endif +{ + Display* dpy; + int major_num,minor_num; + + if ((major_rtrn!=NULL) && (minor_rtrn!=NULL)) { + if (!XkbLibraryVersion(major_rtrn,minor_rtrn)) { + if (reason!=NULL) + *reason= XkbOD_BadLibraryVersion; + return NULL; + } + } + else { + major_num= XkbMajorVersion; + minor_num= XkbMinorVersion; + major_rtrn= &major_num; + minor_rtrn= &minor_num; + } + dpy= XOpenDisplay(name); + if (dpy==NULL) { + if (reason!=NULL) + *reason= XkbOD_ConnectionRefused; + return NULL; + } + if (!XkbQueryExtension(dpy,NULL,ev_rtrn,err_rtrn,major_rtrn,minor_rtrn)) { + if (reason!=NULL) { + if ((*major_rtrn!=0)||(*minor_rtrn!=0)) + *reason= XkbOD_BadServerVersion; + else *reason= XkbOD_NonXkbServer; + } + XCloseDisplay(dpy); + return NULL; + } + if (reason!=NULL) + *reason= XkbOD_Success; + return dpy; +} + +void +#if NeedFunctionPrototypes +XkbSetAtomFuncs(XkbInternAtomFunc getAtom,XkbGetAtomNameFunc getName) +#else +XkbSetAtomFuncs(getAtom,getName) + XkbInternAtomFunc getAtom; + XkbGetAtomNameFunc getName; +#endif +{ + _XkbInternAtomFunc= (getAtom?getAtom:XInternAtom); + _XkbGetAtomNameFunc= (getName?getName:XGetAtomName); + return; +} diff --git a/src/xkb/XKBAlloc.c b/src/xkb/XKBAlloc.c new file mode 100644 index 00000000..82e98f4b --- /dev/null +++ b/src/xkb/XKBAlloc.c @@ -0,0 +1,587 @@ +/* $Xorg: XKBAlloc.c,v 1.4 2000/08/17 19:44:59 cpqbld Exp $ */ +/************************************************************ +Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc. + +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 Silicon Graphics not be +used in advertising or publicity pertaining to distribution +of the software without specific prior written permission. +Silicon Graphics makes no representation about the suitability +of this software for any purpose. It is provided "as is" +without any express or implied warranty. + +SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS +SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON +GRAPHICS 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. + +********************************************************/ + +#ifndef XKB_IN_SERVER + +#include <stdio.h> +#define NEED_REPLIES +#define NEED_EVENTS +#include "Xlibint.h" +#include "XKBlibint.h" +#include <X11/extensions/XKBgeom.h> +#include <X11/extensions/XKBproto.h> +#include "XKBlibint.h" + +#else + +#include <stdio.h> +#include "X.h" +#define NEED_EVENTS +#define NEED_REPLIES +#include "Xproto.h" +#include "misc.h" +#include "inputstr.h" +#include "XKBsrv.h" +#include "XKBgeom.h" + +#endif /* XKB_IN_SERVER */ + +/***===================================================================***/ + +/*ARGSUSED*/ +Status +#if NeedFunctionPrototypes +XkbAllocCompatMap(XkbDescPtr xkb,unsigned which,unsigned nSI) +#else +XkbAllocCompatMap(xkb,which,nSI) + XkbDescPtr xkb; + unsigned which; + unsigned nSI; +#endif +{ +XkbCompatMapPtr compat; +XkbSymInterpretRec *prev_interpret; + + if (!xkb) + return BadMatch; + if (xkb->compat) { + if (xkb->compat->size_si>=nSI) + return Success; + compat= xkb->compat; + compat->size_si= nSI; + if (compat->sym_interpret==NULL) + compat->num_si= 0; + prev_interpret = compat->sym_interpret; + compat->sym_interpret= _XkbTypedRealloc(compat->sym_interpret, + nSI,XkbSymInterpretRec); + if (compat->sym_interpret==NULL) { + _XkbFree(prev_interpret); + compat->size_si= compat->num_si= 0; + return BadAlloc; + } + if (compat->num_si!=0) { + _XkbClearElems(compat->sym_interpret,compat->num_si, + compat->size_si-1,XkbSymInterpretRec); + } + return Success; + } + compat= _XkbTypedCalloc(1,XkbCompatMapRec); + if (compat==NULL) + return BadAlloc; + if (nSI>0) { + compat->sym_interpret= _XkbTypedCalloc(nSI,XkbSymInterpretRec); + if (!compat->sym_interpret) { + _XkbFree(compat); + return BadAlloc; + } + } + compat->size_si= nSI; + compat->num_si= 0; + bzero((char *)&compat->groups[0],XkbNumKbdGroups*sizeof(XkbModsRec)); + xkb->compat= compat; + return Success; +} + + +void +#if NeedFunctionPrototypes +XkbFreeCompatMap(XkbDescPtr xkb,unsigned which,Bool freeMap) +#else +XkbFreeCompatMap(xkb,which,freeMap) + XkbDescPtr xkb; + unsigned which; + Bool freeMap; +#endif +{ +register XkbCompatMapPtr compat; + + if ((xkb==NULL)||(xkb->compat==NULL)) + return; + compat= xkb->compat; + if (freeMap) + which= XkbAllCompatMask; + if (which&XkbGroupCompatMask) + bzero((char *)&compat->groups[0],XkbNumKbdGroups*sizeof(XkbModsRec)); + if (which&XkbSymInterpMask) { + if ((compat->sym_interpret)&&(compat->size_si>0)) + _XkbFree(compat->sym_interpret); + compat->size_si= compat->num_si= 0; + compat->sym_interpret= NULL; + } + if (freeMap) { + _XkbFree(compat); + xkb->compat= NULL; + } + return; +} + +/***===================================================================***/ + +Status +#if NeedFunctionPrototypes +XkbAllocNames(XkbDescPtr xkb,unsigned which,int nTotalRG,int nTotalAliases) +#else +XkbAllocNames(xkb,which,nTotalRG,nTotalAliases) + XkbDescPtr xkb; + unsigned which; + int nTotalRG; + int nTotalAliases; +#endif +{ +XkbNamesPtr names; + + if (xkb==NULL) + return BadMatch; + if (xkb->names==NULL) { + xkb->names = _XkbTypedCalloc(1,XkbNamesRec); + if (xkb->names==NULL) + return BadAlloc; + } + names= xkb->names; + if ((which&XkbKTLevelNamesMask)&&(xkb->map!=NULL)&&(xkb->map->types!=NULL)){ + register int i; + XkbKeyTypePtr type; + + type= xkb->map->types; + for (i=0;i<xkb->map->num_types;i++,type++) { + if (type->level_names==NULL) { + type->level_names= _XkbTypedCalloc(type->num_levels,Atom); + if (type->level_names==NULL) + return BadAlloc; + } + } + } + if ((which&XkbKeyNamesMask)&&(names->keys==NULL)) { + if ((!XkbIsLegalKeycode(xkb->min_key_code))|| + (!XkbIsLegalKeycode(xkb->max_key_code))|| + (xkb->max_key_code<xkb->min_key_code)) + return BadValue; + names->keys= _XkbTypedCalloc((xkb->max_key_code+1),XkbKeyNameRec); + if (names->keys==NULL) + return BadAlloc; + } + if ((which&XkbKeyAliasesMask)&&(nTotalAliases>0)) { + if (names->key_aliases==NULL) { + names->key_aliases= _XkbTypedCalloc(nTotalAliases,XkbKeyAliasRec); + } + else if (nTotalAliases>names->num_key_aliases) { + XkbKeyAliasRec *prev_aliases = names->key_aliases; + + names->key_aliases= _XkbTypedRealloc(names->key_aliases, + nTotalAliases,XkbKeyAliasRec); + if (names->key_aliases!=NULL) { + _XkbClearElems(names->key_aliases,names->num_key_aliases, + nTotalAliases-1,XkbKeyAliasRec); + } else { + _XkbFree(prev_aliases); + } + } + if (names->key_aliases==NULL) { + names->num_key_aliases= 0; + return BadAlloc; + } + names->num_key_aliases= nTotalAliases; + } + if ((which&XkbRGNamesMask)&&(nTotalRG>0)) { + if (names->radio_groups==NULL) { + names->radio_groups= _XkbTypedCalloc(nTotalRG,Atom); + } + else if (nTotalRG>names->num_rg) { + Atom *prev_radio_groups = names->radio_groups; + + names->radio_groups= _XkbTypedRealloc(names->radio_groups,nTotalRG, + Atom); + if (names->radio_groups!=NULL) { + _XkbClearElems(names->radio_groups,names->num_rg,nTotalRG-1, + Atom); + } else { + _XkbFree(prev_radio_groups); + } + } + if (names->radio_groups==NULL) + return BadAlloc; + names->num_rg= nTotalRG; + } + return Success; +} + +void +#if NeedFunctionPrototypes +XkbFreeNames(XkbDescPtr xkb,unsigned which,Bool freeMap) +#else +XkbFreeNames(xkb,which,freeMap) + XkbDescPtr xkb; + unsigned which; + Bool freeMap; +#endif +{ +XkbNamesPtr names; + + if ((xkb==NULL)||(xkb->names==NULL)) + return; + names= xkb->names; + if (freeMap) + which= XkbAllNamesMask; + if (which&XkbKTLevelNamesMask) { + XkbClientMapPtr map= xkb->map; + if ((map!=NULL)&&(map->types!=NULL)) { + register int i; + register XkbKeyTypePtr type; + type= map->types; + for (i=0;i<map->num_types;i++,type++) { + if (type->level_names!=NULL) { + _XkbFree(type->level_names); + type->level_names= NULL; + } + } + } + } + if ((which&XkbKeyNamesMask)&&(names->keys!=NULL)) { + _XkbFree(names->keys); + names->keys= NULL; + names->num_keys= 0; + } + if ((which&XkbKeyAliasesMask)&&(names->key_aliases)){ + _XkbFree(names->key_aliases); + names->key_aliases=NULL; + names->num_key_aliases=0; + } + if ((which&XkbRGNamesMask)&&(names->radio_groups)) { + _XkbFree(names->radio_groups); + names->radio_groups= NULL; + names->num_rg= 0; + } + if (freeMap) { + _XkbFree(names); + xkb->names= NULL; + } + return; +} + +/***===================================================================***/ + +/*ARGSUSED*/ +Status +#if NeedFunctionPrototypes +XkbAllocControls(XkbDescPtr xkb,unsigned which) +#else +XkbAllocControls(xkb,which) + XkbDescPtr xkb; + unsigned which; +#endif +{ + if (xkb==NULL) + return BadMatch; + + if (xkb->ctrls==NULL) { + xkb->ctrls= _XkbTypedCalloc(1,XkbControlsRec); + if (!xkb->ctrls) + return BadAlloc; + } + return Success; +} + +/*ARGSUSED*/ +void +#if NeedFunctionPrototypes +XkbFreeControls(XkbDescPtr xkb,unsigned which,Bool freeMap) +#else +XkbFreeControls(xkb,which,freeMap) + XkbDescPtr xkb; + unsigned which; + Bool freeMap; +#endif +{ + if (freeMap && (xkb!=NULL) && (xkb->ctrls!=NULL)) { + _XkbFree(xkb->ctrls); + xkb->ctrls= NULL; + } + return; +} + +/***===================================================================***/ + +Status +#if NeedFunctionPrototypes +XkbAllocIndicatorMaps(XkbDescPtr xkb) +#else +XkbAllocIndicatorMaps(xkb) + XkbDescPtr xkb; +#endif +{ + if (xkb==NULL) + return BadMatch; + if (xkb->indicators==NULL) { + xkb->indicators= _XkbTypedCalloc(1,XkbIndicatorRec); + if (!xkb->indicators) + return BadAlloc; + } + return Success; +} + +void +#if NeedFunctionPrototypes +XkbFreeIndicatorMaps(XkbDescPtr xkb) +#else +XkbFreeIndicatorMaps(xkb) + XkbDescPtr xkb; +#endif +{ + if ((xkb!=NULL)&&(xkb->indicators!=NULL)) { + _XkbFree(xkb->indicators); + xkb->indicators= NULL; + } + return; +} + +/***====================================================================***/ + +XkbDescRec * +#if NeedFunctionPrototypes +XkbAllocKeyboard(void) +#else +XkbAllocKeyboard() +#endif +{ +XkbDescRec *xkb; + + xkb = _XkbTypedCalloc(1,XkbDescRec); + if (xkb) + xkb->device_spec= XkbUseCoreKbd; + return xkb; +} + +void +#if NeedFunctionPrototypes +XkbFreeKeyboard(XkbDescPtr xkb,unsigned which,Bool freeAll) +#else +XkbFreeKeyboard(xkb,which,freeAll) + XkbDescPtr xkb; + unsigned which; + Bool freeAll; +#endif +{ + if (xkb==NULL) + return; + if (freeAll) + which= XkbAllComponentsMask; + if (which&XkbClientMapMask) + XkbFreeClientMap(xkb,XkbAllClientInfoMask,True); + if (which&XkbServerMapMask) + XkbFreeServerMap(xkb,XkbAllServerInfoMask,True); + if (which&XkbCompatMapMask) + XkbFreeCompatMap(xkb,XkbAllCompatMask,True); + if (which&XkbIndicatorMapMask) + XkbFreeIndicatorMaps(xkb); + if (which&XkbNamesMask) + XkbFreeNames(xkb,XkbAllNamesMask,True); + if ((which&XkbGeometryMask) && (xkb->geom!=NULL)) + XkbFreeGeometry(xkb->geom,XkbGeomAllMask,True); + if (which&XkbControlsMask) + XkbFreeControls(xkb,XkbAllControlsMask,True); + if (freeAll) + _XkbFree(xkb); + return; +} + +/***====================================================================***/ + +XkbDeviceLedInfoPtr +#if NeedFunctionPrototypes +XkbAddDeviceLedInfo(XkbDeviceInfoPtr devi,unsigned ledClass,unsigned ledId) +#else +XkbAddDeviceLedInfo(devi,ledClass,ledId) + XkbDeviceInfoPtr devi; + unsigned ledClass; + unsigned ledId; +#endif +{ +XkbDeviceLedInfoPtr devli; +register int i; + + if ((!devi)||(!XkbSingleXIClass(ledClass))||(!XkbSingleXIId(ledId))) + return NULL; + for (i=0,devli=devi->leds;i<devi->num_leds;i++,devli++) { + if ((devli->led_class==ledClass)&&(devli->led_id==ledId)) + return devli; + } + if (devi->num_leds>=devi->sz_leds) { + XkbDeviceLedInfoRec *prev_leds = devi->leds; + + if (devi->sz_leds>0) devi->sz_leds*= 2; + else devi->sz_leds= 1; + devi->leds= _XkbTypedRealloc(devi->leds,devi->sz_leds, + XkbDeviceLedInfoRec); + if (!devi->leds) { + _XkbFree(prev_leds); + devi->sz_leds= devi->num_leds= 0; + return NULL; + } + i= devi->num_leds; + for (devli=&devi->leds[i];i<devi->sz_leds;i++,devli++) { + bzero(devli,sizeof(XkbDeviceLedInfoRec)); + devli->led_class= XkbXINone; + devli->led_id= XkbXINone; + } + } + devli= &devi->leds[devi->num_leds++]; + bzero(devli,sizeof(XkbDeviceLedInfoRec)); + devli->led_class= ledClass; + devli->led_id= ledId; + return devli; +} + +Status +#if NeedFunctionPrototypes +XkbResizeDeviceButtonActions(XkbDeviceInfoPtr devi,unsigned newTotal) +#else +XkbResizeDeviceButtonActions(devi,newTotal) + XkbDeviceInfoPtr devi; + unsigned newTotal; +#endif +{ + XkbAction *prev_btn_acts; + + if ((!devi)||(newTotal>255)) + return BadValue; + if ((devi->btn_acts!=NULL)&&(newTotal==devi->num_btns)) + return Success; + if (newTotal==0) { + if (devi->btn_acts!=NULL) { + _XkbFree(devi->btn_acts); + devi->btn_acts= NULL; + } + devi->num_btns= 0; + return Success; + } + prev_btn_acts = devi->btn_acts; + devi->btn_acts= _XkbTypedRealloc(devi->btn_acts,newTotal,XkbAction); + if (devi->btn_acts==NULL) { + _XkbFree(prev_btn_acts); + devi->num_btns= 0; + return BadAlloc; + } + if (newTotal>devi->num_btns) { + XkbAction *act; + act= &devi->btn_acts[devi->num_btns]; + bzero((char *)act,(newTotal-devi->num_btns)*sizeof(XkbAction)); + } + devi->num_btns= newTotal; + return Success; +} + +/*ARGSUSED*/ +XkbDeviceInfoPtr +#if NeedFunctionPrototypes +XkbAllocDeviceInfo(unsigned deviceSpec,unsigned nButtons,unsigned szLeds) +#else +XkbAllocDeviceInfo(deviceSpec,nButtons,szLeds) + unsigned deviceSpec; + unsigned nButtons; + unsigned szLeds; +#endif +{ +XkbDeviceInfoPtr devi; + + devi= _XkbTypedCalloc(1,XkbDeviceInfoRec); + if (devi!=NULL) { + devi->device_spec= deviceSpec; + devi->has_own_state= False; + devi->num_btns= 0; + devi->btn_acts= NULL; + if (nButtons>0) { + devi->num_btns= nButtons; + devi->btn_acts= _XkbTypedCalloc(nButtons,XkbAction); + if (!devi->btn_acts) { + _XkbFree(devi); + return NULL; + } + } + devi->dflt_kbd_fb= XkbXINone; + devi->dflt_led_fb= XkbXINone; + devi->num_leds= 0; + devi->sz_leds= 0; + devi->leds= NULL; + if (szLeds>0) { + devi->sz_leds= szLeds; + devi->leds= _XkbTypedCalloc(szLeds,XkbDeviceLedInfoRec); + if (!devi->leds) { + if (devi->btn_acts) + _XkbFree(devi->btn_acts); + _XkbFree(devi); + return NULL; + } + } + } + return devi; +} + + +void +#if NeedFunctionPrototypes +XkbFreeDeviceInfo(XkbDeviceInfoPtr devi,unsigned which,Bool freeDevI) +#else +XkbFreeDeviceInfo(devi,which,freeDevI) + XkbDeviceInfoPtr devi; + unsigned which; + Bool freeDevI; +#endif +{ + if (devi) { + if (freeDevI) { + which= XkbXI_AllDeviceFeaturesMask; + if (devi->name) { + _XkbFree(devi->name); + devi->name= NULL; + } + } + if ((which&XkbXI_ButtonActionsMask)&&(devi->btn_acts)) { + _XkbFree(devi->btn_acts); + devi->num_btns= 0; + devi->btn_acts= NULL; + } + if ((which&XkbXI_IndicatorsMask)&&(devi->leds)) { + register int i; + if ((which&XkbXI_IndicatorsMask)==XkbXI_IndicatorsMask) { + _XkbFree(devi->leds); + devi->sz_leds= devi->num_leds= 0; + devi->leds= NULL; + } + else { + XkbDeviceLedInfoPtr devli; + for (i=0,devli=devi->leds;i<devi->num_leds;i++,devli++) { + if (which&XkbXI_IndicatorMapsMask) + bzero((char *)&devli->maps[0],sizeof(devli->maps)); + else bzero((char *)&devli->names[0],sizeof(devli->names)); + } + } + } + if (freeDevI) + _XkbFree(devi); + } + return; +} diff --git a/src/xkb/XKBBell.c b/src/xkb/XKBBell.c new file mode 100644 index 00000000..3b6bb850 --- /dev/null +++ b/src/xkb/XKBBell.c @@ -0,0 +1,231 @@ +/* $Xorg: XKBBell.c,v 1.3 2000/08/17 19:45:00 cpqbld Exp $ */ +/************************************************************ +Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc. + +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 Silicon Graphics not be +used in advertising or publicity pertaining to distribution +of the software without specific prior written permission. +Silicon Graphics makes no representation about the suitability +of this software for any purpose. It is provided "as is" +without any express or implied warranty. + +SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS +SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON +GRAPHICS 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. + +********************************************************/ + +#include <stdio.h> +#define NEED_REPLIES +#define NEED_EVENTS +#include "Xlibint.h" +#include <X11/extensions/XKBproto.h> +#include "XKBlibint.h" + + +Bool +#if NeedFunctionPrototypes +XkbDeviceBell( Display * dpy, + Window window, + int deviceID, + int bellClass, + int bellID, + int percent, + Atom name) +#else +XkbDeviceBell(dpy,window,deviceID,bellClass,bellID,percent,name) + Display *dpy; + Window window; + int deviceID; + int bellClass; + int bellID; + int percent; + Atom name; +#endif +{ + register xkbBellReq *req; + XkbInfoPtr xkbi; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) + return False; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbBell,req); + req->reqType = xkbi->codes->major_opcode; + req->xkbReqType = X_kbBell; + req->deviceSpec = deviceID; + req->window = (CARD32)window; + req->bellClass = (CARD16)bellClass; + req->bellID = (CARD16)bellID; + req->percent = percent; + req->forceSound = False; + req->eventOnly = False; + req->pitch = 0; + req->duration = 0; + req->name = (CARD32)name; + req->pad1= 0; req->pad2= 0; + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + +Bool +#if NeedFunctionPrototypes +XkbForceDeviceBell( Display * dpy, + int deviceID, + int bellClass, + int bellID, + int percent) +#else +XkbForceDeviceBell(dpy,deviceID,bellClass,bellID,percent) + Display *dpy; + int deviceID; + int bellClass; + int bellID; + int percent; +#endif +{ + register xkbBellReq *req; + XkbInfoPtr xkbi; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) + return False; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbBell,req); + req->reqType = xkbi->codes->major_opcode; + req->xkbReqType = X_kbBell; + req->deviceSpec = deviceID; + req->window = (CARD32)None; + req->bellClass = (CARD16)bellClass; + req->bellID = (CARD16)bellID; + req->percent = percent; + req->forceSound = True; + req->eventOnly = False; + req->pitch = 0; + req->duration = 0; + req->name = None; + req->pad1= 0; req->pad2= 0; + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + +Bool +#if NeedFunctionPrototypes +XkbDeviceBellEvent( Display * dpy, + Window window, + int deviceID, + int bellClass, + int bellID, + int percent, + Atom name) +#else +XkbDeviceBellEvent(dpy,window,deviceID,bellClass,bellID,percent,name) + Display *dpy; + Window window; + int deviceID; + int bellClass; + int bellID; + int percent; + Atom name; +#endif +{ + register xkbBellReq *req; + XkbInfoPtr xkbi; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) + return False; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbBell,req); + req->reqType = xkbi->codes->major_opcode; + req->xkbReqType = X_kbBell; + req->deviceSpec = deviceID; + req->window = (CARD32)window; + req->bellClass = (CARD16)bellClass; + req->bellID = (CARD16)bellID; + req->percent = percent; + req->forceSound = False; + req->eventOnly = True; + req->pitch = 0; + req->duration = 0; + req->name = (CARD32)name; + req->pad1= 0; req->pad2= 0; + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + +Bool +#if NeedFunctionPrototypes +XkbBell(Display *dpy,Window window,int percent,Atom name) +#else +XkbBell(dpy,window,percent,name) + Display *dpy; + Window window; + int percent; + Atom name; +#endif +{ + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) { + XBell(dpy,percent); + return False; + } + return XkbDeviceBell(dpy,window,XkbUseCoreKbd,XkbDfltXIClass,XkbDfltXIId, + percent,name); +} + +Bool +#if NeedFunctionPrototypes +XkbForceBell(Display *dpy,int percent) +#else +XkbForceBell(dpy,percent) + Display * dpy; + int percent; +#endif +{ + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) { + XBell(dpy,percent); + return False; + } + return XkbForceDeviceBell(dpy,XkbUseCoreKbd,XkbDfltXIClass,XkbDfltXIId, + percent); +} + +Bool +#if NeedFunctionPrototypes +XkbBellEvent(Display *dpy,Window window,int percent,Atom name) +#else +XkbBellEvent(dpy,window,percent,name) + Display *dpy; + Window window; + int percent; + Atom name; +#endif +{ + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) { + return False; + } + /* class 0 = KbdFeedbackClass (X Input Extension) */ + return XkbDeviceBellEvent(dpy,window,XkbUseCoreKbd, + XkbDfltXIClass,XkbDfltXIId, + percent,name); +} + diff --git a/src/xkb/XKBBind.c b/src/xkb/XKBBind.c new file mode 100644 index 00000000..4c6334a7 --- /dev/null +++ b/src/xkb/XKBBind.c @@ -0,0 +1,963 @@ +/* $Xorg: XKBBind.c,v 1.4 2001/02/09 02:03:37 xorgcvs Exp $ */ +/* + +Copyright 1985, 1987, 1994, 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. + +*/ + /* the new monsters ate the old ones */ + +#define NEED_EVENTS +#include <X11/Xlibint.h> +#include <X11/Xutil.h> +#include <X11/keysym.h> +#include <stdio.h> +#include <ctype.h> + +#include <X11/extensions/XKBproto.h> +#include "XKBlibint.h" + +#ifdef USE_OWN_COMPOSE +#define COMPOSE_NO_CONST_MEMBERS +#include "imComp.h" +#endif + +#define AllMods (ShiftMask|LockMask|ControlMask| \ + Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask) + +static int _XkbLoadDpy( +#if NeedFunctionPrototypes + Display *dpy +#endif +); + +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 */ +}; + +KeySym +#if NeedFunctionPrototypes +XkbKeycodeToKeysym(Display *dpy, +#if NeedWidePrototypes + unsigned int kc, +#else + KeyCode kc, +#endif + int group, + int level) +#else +XkbKeycodeToKeysym(dpy, kc, group, level) + Display *dpy; + KeyCode kc; + int group; + int level; +#endif +{ + XkbDescRec *xkb; + + if (_XkbUnavailable(dpy)) + return NoSymbol; + + _XkbCheckPendingRefresh(dpy,dpy->xkb_info); + + xkb = dpy->xkb_info->desc; + if ((kc<xkb->min_key_code)||(kc>xkb->max_key_code)) + return NoSymbol; + + if ((group<0)||(level<0)||(group>=XkbKeyNumGroups(xkb,kc))) + return NoSymbol; + if (level>=XkbKeyGroupWidth(xkb,kc,group)) { + /* for compatibility with the core protocol, _always_ allow */ + /* two symbols in the first two groups. If either of the */ + /* two is of type ONE_LEVEL, just replicate the first symbol */ + if ((group>XkbGroup2Index)||(XkbKeyGroupWidth(xkb,kc,group)!=1)|| + (level!=1)) { + return NoSymbol; + } + level= 0; + } + return XkbKeySymEntry(xkb,kc,level,group); +} + +KeySym +#if NeedFunctionPrototypes +XKeycodeToKeysym(Display *dpy, +#if NeedWidePrototypes + unsigned int kc, +#else + KeyCode kc, +#endif + int col) +#else +XKeycodeToKeysym(dpy, kc, col) + Display *dpy; + KeyCode kc; + int col; +#endif +{ + XkbDescRec *xkb; + + if (_XkbUnavailable(dpy)) + return _XKeycodeToKeysym(dpy, kc, col); + + _XkbCheckPendingRefresh(dpy,dpy->xkb_info); + + xkb = dpy->xkb_info->desc; + if ((kc<xkb->min_key_code)||(kc>xkb->max_key_code)) + return NoSymbol; + + if (col>3) { + int lastSym,tmp,nGrp; + + lastSym= 3; + nGrp= XkbKeyNumGroups(xkb,kc); + if ((nGrp>0)&&((tmp=XkbKeyGroupWidth(xkb,kc,XkbGroup1Index))>2)) { + if (col<=(lastSym+tmp-2)) + return XkbKeycodeToKeysym(dpy,kc,XkbGroup1Index,col-lastSym+2); + lastSym+= tmp-2; + } + if ((nGrp>1)&&((tmp=XkbKeyGroupWidth(xkb,kc,XkbGroup2Index))>2)) { + if (col<=(lastSym+tmp-2)) + return XkbKeycodeToKeysym(dpy,kc,XkbGroup2Index,col-lastSym+2); + lastSym+= tmp-2; + } + if (nGrp>2) { + tmp= XkbKeyGroupWidth(xkb,kc,XkbGroup3Index); + if (col<=lastSym+tmp) + return XkbKeycodeToKeysym(dpy,kc,XkbGroup3Index,col-lastSym); + lastSym+= tmp; + } + if (nGrp>3) { + tmp= XkbKeyGroupWidth(xkb,kc,XkbGroup4Index); + if (col<=lastSym+tmp) + return XkbKeycodeToKeysym(dpy,kc,XkbGroup4Index,col-lastSym); + } + return NoSymbol; + } + return XkbKeycodeToKeysym(dpy,kc,(col>>1),(col&1)); +} + +KeyCode +#if NeedFunctionPrototypes +XKeysymToKeycode(Display *dpy, KeySym ks) +#else +XKeysymToKeycode(dpy, ks) + Display *dpy; + KeySym ks; +#endif +{ + register int i, j, gotOne; + + if (_XkbUnavailable(dpy)) + return _XKeysymToKeycode(dpy,ks); + _XkbCheckPendingRefresh(dpy,dpy->xkb_info); + + j= 0; + do { + register XkbDescRec *xkb = dpy->xkb_info->desc; + gotOne= 0; + for (i = dpy->min_keycode; i <= dpy->max_keycode; i++) { + if ( j<(int)XkbKeyNumSyms(xkb,i) ) { + gotOne = 1; + if ((XkbKeySym(xkb,i,j)==ks)) + return i; + } + } + j++; + } while (gotOne); + return 0; +} + +static int +#if NeedFunctionPrototypes +_XkbComputeModmap(Display *dpy) +#else +_XkbComputeModmap(dpy) + Display *dpy; +#endif +{ +register XkbDescPtr xkb; + + xkb= dpy->xkb_info->desc; + if (XkbGetUpdatedMap(dpy,XkbModifierMapMask,xkb)==Success) + return 1; + return 0; +} + +unsigned +#if NeedFunctionPrototypes +XkbKeysymToModifiers(Display *dpy,KeySym ks) +#else +XkbKeysymToModifiers(dpy,ks) + Display *dpy; + KeySym ks; +#endif +{ + XkbDescRec *xkb; + register int i,j; + register KeySym *pSyms; + CARD8 mods; + + if (_XkbUnavailable(dpy)) + return _XKeysymToModifiers(dpy,ks); + _XkbCheckPendingRefresh(dpy,dpy->xkb_info); + + if (_XkbNeedModmap(dpy->xkb_info)&&(!_XkbComputeModmap(dpy))) + return _XKeysymToModifiers(dpy,ks); + + xkb= dpy->xkb_info->desc; + mods= 0; + for (i = xkb->min_key_code; i <= (int)xkb->max_key_code; i++) { + pSyms= XkbKeySymsPtr(xkb,i); + for (j=XkbKeyNumSyms(xkb,i)-1;j>=0;j--) { + if (pSyms[j]==ks) { + mods|= xkb->map->modmap[i]; + break; + } + } + } + return mods; +} + +KeySym +#if NeedFunctionPrototypes +XLookupKeysym(register XKeyEvent *event, int col) +#else +XLookupKeysym(event, col) + register XKeyEvent *event; + int col; +#endif +{ + Display *dpy = event->display; + if (_XkbUnavailable(dpy)) + return _XLookupKeysym(event, col); + _XkbCheckPendingRefresh(dpy,dpy->xkb_info); + return XKeycodeToKeysym(dpy, event->keycode, col); +} + + /* + * Not a public entry point -- XkbTranslateKey is an obsolete name + * that is preserved here so that functions linked against the old + * version will continue to work in a shared library environment. + */ +int +#if NeedFunctionPrototypes +XkbTranslateKey( register Display * dpy, + KeyCode key, + register unsigned int mods, + unsigned int * mods_rtrn, + KeySym * keysym_rtrn) +#else +XkbTranslateKey(dpy, key, mods, mods_rtrn, keysym_rtrn) + register Display *dpy; + KeyCode key; + register unsigned int mods; + unsigned int *mods_rtrn; + KeySym *keysym_rtrn; +#endif +{ + return XkbLookupKeySym(dpy,key,mods,mods_rtrn,keysym_rtrn); +} + +Bool +#if NeedFunctionPrototypes +XkbLookupKeySym( register Display * dpy, + KeyCode key, + register unsigned int mods, + unsigned int * mods_rtrn, + KeySym * keysym_rtrn) +#else +XkbLookupKeySym(dpy, key, mods, mods_rtrn, keysym_rtrn) + register Display *dpy; + KeyCode key; + register unsigned int mods; + unsigned int *mods_rtrn; + KeySym *keysym_rtrn; +#endif +{ + if (_XkbUnavailable(dpy)) + return _XTranslateKey(dpy, key, mods, mods_rtrn, keysym_rtrn); + _XkbCheckPendingRefresh(dpy,dpy->xkb_info); + return XkbTranslateKeyCode(dpy->xkb_info->desc,key,mods,mods_rtrn, + keysym_rtrn); +} + +Bool +#if NeedFunctionPrototypes +XkbTranslateKeyCode( register XkbDescPtr xkb, + KeyCode key, + register unsigned int mods, + unsigned int * mods_rtrn, + KeySym * keysym_rtrn) +#else +XkbTranslateKeyCode(xkb, key, mods, mods_rtrn, keysym_rtrn) + register XkbDescPtr xkb; + KeyCode key; + register unsigned int mods; + unsigned int *mods_rtrn; + KeySym *keysym_rtrn; +#endif +{ + XkbKeyTypeRec *type; + int col,nKeyGroups; + unsigned preserve,effectiveGroup; + KeySym *syms; + + if (mods_rtrn!=NULL) + *mods_rtrn = 0; + + nKeyGroups= XkbKeyNumGroups(xkb,key); + if ((!XkbKeycodeInRange(xkb,key))||(nKeyGroups==0)) { + if (keysym_rtrn!=NULL) + *keysym_rtrn = NoSymbol; + return False; + } + + syms = XkbKeySymsPtr(xkb,key); + + /* find the offset of the effective group */ + col = 0; + effectiveGroup= XkbGroupForCoreState(mods); + if ( effectiveGroup>=nKeyGroups ) { + unsigned groupInfo= XkbKeyGroupInfo(xkb,key); + switch (XkbOutOfRangeGroupAction(groupInfo)) { + default: + effectiveGroup %= nKeyGroups; + break; + case XkbClampIntoRange: + effectiveGroup = nKeyGroups-1; + break; + case XkbRedirectIntoRange: + effectiveGroup = XkbOutOfRangeGroupNumber(groupInfo); + if (effectiveGroup>=nKeyGroups) + effectiveGroup= 0; + break; + } + } + col= effectiveGroup*XkbKeyGroupsWidth(xkb,key); + type = XkbKeyKeyType(xkb,key,effectiveGroup); + + preserve= 0; + if (type->map) { /* find the column (shift level) within the group */ + register int i; + register XkbKTMapEntryPtr entry; + for (i=0,entry=type->map;i<type->map_count;i++,entry++) { + if ((entry->active)&&((mods&type->mods.mask)==entry->mods.mask)) { + col+= entry->level; + if (type->preserve) + preserve= type->preserve[i].mask; + break; + } + } + } + + if (keysym_rtrn!=NULL) + *keysym_rtrn= syms[col]; + if (mods_rtrn) { + *mods_rtrn= type->mods.mask&(~preserve); + /* The Motif VTS doesn't get the help callback called if help + * is bound to Shift+<whatever>, and it appears as though it + * is XkbTranslateKeyCode that is causing the problem. The + * core X version of XTranslateKey always OR's in ShiftMask + * and LockMask for mods_rtrn, so this "fix" keeps this behavior + * and solves the VTS problem. + */ + if ((xkb->dpy)&&(xkb->dpy->xkb_info)&& + (xkb->dpy->xkb_info->xlib_ctrls&XkbLC_AlwaysConsumeShiftAndLock)) { + *mods_rtrn|= (ShiftMask|LockMask); + } + } + return (syms[col]!=NoSymbol); +} + +Status +#if NeedFunctionPrototypes +XkbRefreshKeyboardMapping(register XkbMapNotifyEvent *event) +#else +XkbRefreshKeyboardMapping(event) + register XkbMapNotifyEvent *event; +#endif +{ + Display *dpy = event->display; + XkbInfoPtr xkbi; + + if (_XkbUnavailable(dpy)) { + _XRefreshKeyboardMapping((XMappingEvent *)event); + return Success; + } + xkbi= dpy->xkb_info; + + if (((event->type&0x7f)-xkbi->codes->first_event)!=XkbEventCode) + return BadMatch; + if (event->xkb_type==XkbNewKeyboardNotify) { + _XkbReloadDpy(dpy); + return Success; + } + if (event->xkb_type==XkbMapNotify) { + XkbMapChangesRec changes; + Status rtrn; + + if (xkbi->flags&XkbMapPending) + changes= xkbi->changes; + else bzero(&changes,sizeof(XkbChangesRec)); + XkbNoteMapChanges(&changes,event,XKB_XLIB_MAP_MASK); + LockDisplay(dpy); + if ((rtrn=XkbGetMapChanges(dpy,xkbi->desc,&changes))!=Success) { +#ifdef DEBUG + fprintf(stderr,"Internal Error! XkbGetMapChanges failed:\n"); +#endif + xkbi->changes= changes; + } + else if (xkbi->flags&XkbMapPending) { + xkbi->flags&= ~XkbMapPending; + bzero(&xkbi->changes,sizeof(XkbMapChangesRec)); + } + UnlockDisplay(dpy); + return rtrn; + } + return BadMatch; +} + +int +#if NeedFunctionPrototypes +XRefreshKeyboardMapping(register XMappingEvent *event) +#else +XRefreshKeyboardMapping(event) + register XMappingEvent *event; +#endif +{ + XkbEvent *xkbevent = (XkbEvent *)event; + Display *dpy = event->display; + XkbMapChangesRec changes; + XkbInfoPtr xkbi; + + if (_XkbUnavailable(dpy)) + return _XRefreshKeyboardMapping(event); + + xkbi = dpy->xkb_info; + + if (((event->type&0x7f)-xkbi->codes->first_event)==XkbEventCode) + return XkbRefreshKeyboardMapping(&xkbevent->map); + + if (xkbi->flags&XkbXlibNewKeyboard) { + _XkbReloadDpy(dpy); + return 1; + } + + if ((xkbi->flags&XkbMapPending)||(event->request==MappingKeyboard)) { + if (xkbi->flags&XkbMapPending) { + changes= xkbi->changes; + _XkbNoteCoreMapChanges(&changes,event,XKB_XLIB_MAP_MASK); + } + else { + bzero(&changes,sizeof(changes)); + changes.changed= XkbKeySymsMask; + if (xkbi->desc->min_key_code<xkbi->desc->max_key_code) { + changes.first_key_sym= xkbi->desc->min_key_code; + changes.num_key_syms= xkbi->desc->max_key_code- + xkbi->desc->min_key_code+1; + } + else { + changes.first_key_sym= event->first_keycode; + changes.num_key_syms= event->count; + } + } + + if (XkbGetMapChanges(dpy,xkbi->desc, &changes)!=Success) { +#ifdef DEBUG + fprintf(stderr,"Internal Error! XkbGetMapChanges failed:\n"); + if (changes.changed&XkbKeyTypesMask) { + int first= changes.first_type; + int last= changes.first_type+changes.num_types-1; + fprintf(stderr," types: %d..%d\n",first,last); + } + if (changes.changed&XkbKeySymsMask) { + int first= changes.first_key_sym; + int last= changes.first_key_sym+changes.num_key_syms-1; + fprintf(stderr," symbols: %d..%d\n",first,last); + } + if (changes.changed&XkbKeyActionsMask) { + int last,first= changes.first_key_act; + last= changes.first_key_act+changes.num_key_acts-1; + fprintf(stderr," acts: %d..%d\n",first,last); + } + if (changes.changed&XkbKeyBehaviorsMask) { + int last,first= changes.first_key_behavior; + last= first+changes.num_key_behaviors-1; + fprintf(stderr," behaviors: %d..%d\n",first,last); + } + if (changes.changed&XkbVirtualModsMask) { + fprintf(stderr,"virtual mods: 0x%04x\n", + changes.vmods); + } + if (changes.changed&XkbExplicitComponentsMask) { + int last,first= changes.first_key_explicit; + last= first+changes.num_key_explicit-1; + fprintf(stderr," explicit: %d..%d\n",first,last); + } +#endif + } + LockDisplay(dpy); + if (xkbi->flags&XkbMapPending) { + xkbi->flags&= ~XkbMapPending; + bzero(&xkbi->changes,sizeof(XkbMapChangesRec)); + } + UnlockDisplay(dpy); + } + if (event->request==MappingModifier) { + if (xkbi->desc->map->modmap) { + _XkbFree(xkbi->desc->map->modmap); + xkbi->desc->map->modmap= NULL; + } + if (dpy->key_bindings) { + register struct _XKeytrans *p; + for (p = dpy->key_bindings; p; p = p->next) { + register int i; + p->state= 0; + if (p->mlen>0) { + for (i = 0; i < p->mlen; i++) { + p->state|= XkbKeysymToModifiers(dpy,p->modifiers[i]); + } + if (p->state) p->state &= AllMods; + else p->state = AnyModifier; + } + } + } + UnlockDisplay(dpy); + } + return 1; +} + +static int +#if NeedFunctionPrototypes +_XkbLoadDpy(Display *dpy) +#else +_XkbLoadDpy(dpy) + Display *dpy; +#endif +{ + XkbInfoPtr xkbi; + unsigned query,oldEvents; + XkbDescRec *desc; + + if (!XkbUseExtension(dpy,NULL,NULL)) + return 0; + + xkbi = dpy->xkb_info; + query = XkbAllClientInfoMask; + desc = XkbGetMap(dpy,query,XkbUseCoreKbd); + if (!desc) { +#ifdef DEBUG + fprintf(stderr,"Warning! XkbGetMap failed!\n"); +#endif + return 0; + } + LockDisplay(dpy); + xkbi->desc = desc; + + _XkbGetConverters(_XkbGetCharset(),&xkbi->cvt); + _XkbGetConverters("ISO8859-1",&xkbi->latin1cvt); + UnlockDisplay(dpy); + oldEvents= xkbi->selected_events; + if (!(xkbi->xlib_ctrls&XkbLC_IgnoreNewKeyboards)) { + XkbSelectEventDetails(dpy,xkbi->desc->device_spec,XkbNewKeyboardNotify, + XkbNKN_KeycodesMask|XkbNKN_DeviceIDMask, + XkbNKN_KeycodesMask|XkbNKN_DeviceIDMask); + } + XkbSelectEventDetails(dpy,xkbi->desc->device_spec,XkbMapNotify, + XkbAllClientInfoMask,XkbAllClientInfoMask); + LockDisplay(dpy); + xkbi->selected_events= oldEvents; + UnlockDisplay(dpy); + return 1; +} + +void +#if NeedFunctionPrototypes +_XkbReloadDpy(Display *dpy) +#else +_XkbReloadDpy(dpy) + Display *dpy; +#endif +{ + XkbInfoPtr xkbi; + XkbDescRec *desc; + unsigned oldDeviceID; + + if (_XkbUnavailable(dpy)) + return; + + xkbi = dpy->xkb_info; + LockDisplay(dpy); + if (xkbi->desc) { + oldDeviceID= xkbi->desc->device_spec; + XkbFreeKeyboard(xkbi->desc,XkbAllComponentsMask,True); + xkbi->desc= NULL; + xkbi->flags&= ~(XkbMapPending|XkbXlibNewKeyboard); + xkbi->changes.changed= 0; + } + else oldDeviceID= XkbUseCoreKbd; + UnlockDisplay(dpy); + desc = XkbGetMap(dpy,XkbAllClientInfoMask,XkbUseCoreKbd); + if (!desc) + return; + LockDisplay(dpy); + xkbi->desc = desc; + UnlockDisplay(dpy); + + if (desc->device_spec!=oldDeviceID) { + /* transfer(?) event masks here */ +#ifdef NOTYET + unsigned oldEvents; + oldEvents= xkbi->selected_events; + XkbSelectEventDetails(dpy,xkbi->desc->device_spec,XkbMapNotify, + XkbAllMapComponentsMask,XkbAllClientInfoMask); + LockDisplay(dpy); + xkbi->selected_events= oldEvents; + UnlockDisplay(dpy); +#endif + } + return; +} + +int +#if NeedFunctionPrototypes +XkbTranslateKeySym( register Display * dpy, + register KeySym * sym_rtrn, + unsigned int mods, + char * buffer, + int nbytes, + int * extra_rtrn) +#else +XkbTranslateKeySym(dpy, sym_rtrn, mods, buffer, nbytes, extra_rtrn) + register Display *dpy; + register KeySym *sym_rtrn; + unsigned int mods; + char *buffer; + int nbytes; + int *extra_rtrn; +#endif +{ + register XkbInfoPtr xkb; + XkbKSToMBFunc cvtr; + XPointer priv; + char tmp[4]; + register struct _XKeytrans *p; + int n; + + if (extra_rtrn) + *extra_rtrn= 0; + + if (_XkbUnavailable(dpy)) + return _XTranslateKeySym(dpy, *sym_rtrn, mods, buffer, nbytes); + _XkbCheckPendingRefresh(dpy,dpy->xkb_info); + + xkb= dpy->xkb_info; + if ((buffer==NULL)||(nbytes==0)) { + buffer= tmp; + nbytes= 4; + } + + /* see if symbol rebound, if so, return that string. */ + for (p = dpy->key_bindings; p; p = p->next) { + if (((mods & AllMods) == p->state) && (*sym_rtrn == p->key)) { + int tmp = p->len; + if (tmp > nbytes) { + if (extra_rtrn) + *extra_rtrn= tmp-nbytes; + tmp = nbytes; + } + memcpy (buffer, p->string, tmp); + return tmp; + } + } + + if ( nbytes>0 ) + buffer[0]= '\0'; + + if ( xkb->cvt.KSToUpper && (mods&LockMask) ) { + *sym_rtrn = (*xkb->cvt.KSToUpper)(*sym_rtrn); + } + if (xkb->xlib_ctrls & XkbLC_ForceLatin1Lookup) { + cvtr = xkb->latin1cvt.KSToMB; + priv = xkb->latin1cvt.KSToMBPriv; + } else { + cvtr = xkb->cvt.KSToMB; + priv = xkb->cvt.KSToMBPriv; + } + + n = (*cvtr)(priv,*sym_rtrn,buffer,nbytes,extra_rtrn); + + if ((!xkb->cvt.KSToUpper)&&( mods&LockMask )) { + register int i; + + if (!xkb->cvt.KSToUpper) { + int change; + char ch; + for (i=change=0;i<n;i++) { + ch= toupper(buffer[i]); + change= (change||(buffer[i]!=ch)); + buffer[i] = ch; + } + if (change) { + if (n==1) + *sym_rtrn=(*xkb->cvt.MBToKS)(xkb->cvt.MBToKSPriv, + buffer,n,0); + else *sym_rtrn= NoSymbol; + } + } + } + + if ( mods&ControlMask ) { + if ( n==1 ) { + register char c = buffer[0]; + + 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; + if ( nbytes>1 ) + buffer[1]= '\0'; + return 1; + } + if ( nbytes > 0 ) + buffer[0]= '\0'; + return 0; + } + return n; +} + +int +#if NeedFunctionPrototypes +XLookupString ( register XKeyEvent * event, + char * buffer, + int nbytes, + KeySym * keysym, + XComposeStatus * status) +#else +XLookupString (event, buffer, nbytes, keysym, status) + register XKeyEvent *event; + char *buffer; /* buffer */ + int nbytes; /* space in buffer for characters */ + KeySym *keysym; + XComposeStatus *status; +#endif +{ + KeySym dummy; + int rtrnLen; + unsigned int new_mods; + Display *dpy = event->display; + XkbDescPtr xkb; + + if (_XkbUnavailable(dpy)) + return _XLookupString(event, buffer, nbytes, keysym, status); + _XkbCheckPendingRefresh(dpy,dpy->xkb_info); + + if (keysym==NULL) + keysym= &dummy; + xkb= dpy->xkb_info->desc; + if (!XkbTranslateKeyCode(xkb,event->keycode,event->state, &new_mods,keysym)) + return 0; + new_mods= (event->state&(~new_mods)); + +#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(*keysym,event->keycode,status) ) { + XimCompRtrn rtrn; + + switch (XimCompProcessSym(status,*keysym,&rtrn)) { + case XIM_COMP_IGNORE: + break; + case XIM_COMP_IN_PROGRESS: + if ( keysym!=NULL ) + *keysym = NoSymbol; +#ifndef NO_COMPOSE_LED + if ( dpy->xkb_info->xlib_ctrls&XkbLC_ComposeLED ) { + XkbSetNamedIndicator(dpy,dpy->xkb_info->composeLED, + True,True,False,NULL); + } +#endif + return 0; + case XIM_COMP_FAIL: + { + static Atom _ComposeFail= None; + int n = 0, len= 0; +#ifndef NO_COMPOSE_LED + if ( dpy->xkb_info->xlib_ctrls&XkbLC_ComposeLED ) { + XkbSetNamedIndicator(dpy,dpy->xkb_info->composeLED, + True,False,False,NULL); + } +#endif +#ifndef NO_BELL_ON_COMPOSE_FAIL + if (dpy->xkb_info->xlib_ctrls&XkbLC_BeepOnComposeFail) { + if (_ComposeFail==None) + _ComposeFail= XInternAtom(dpy,"ComposeFail",0); + XkbBell(dpy,event->window,0,_ComposeFail); + } +#endif + for (n=len=0;rtrn.sym[n]!=XK_VoidSymbol;n++) { + if ( nbytes-len > 0 ) { + len+= XkbTranslateKeySym(dpy,&rtrn.sym[n],new_mods, + buffer+len,nbytes-len, + NULL); + } + } + if ( keysym!=NULL ) { + if ( n==1 ) *keysym = rtrn.sym[0]; + else *keysym = NoSymbol; + } + return len; + } + case XIM_COMP_SUCCEED: + { + int len,n = 0; + +#ifndef NO_COMPOSE_LED + if ( dpy->xkb_info->xlib_ctrls&XkbLC_ComposeLED ) { + XkbSetNamedIndicator(dpy,dpy->xkb_info->composeLED, + True,False,False,NULL); + } +#endif + *keysym = rtrn.matchSym; + if ( rtrn.str[0]!='\0' ) { + strncpy(buffer,rtrn.str,nbytes-1); + buffer[nbytes-1]= '\0'; + len = (int)strlen(buffer); + } + else { + len = XkbTranslateKeySym(dpy,keysym,new_mods, + buffer,nbytes, + NULL); + } + for (n=0;rtrn.sym[n]!=XK_VoidSymbol;n++) { + if ( nbytes-len > 0 ) { + len+= XkbTranslateKeySym(dpy,&rtrn.sym[n], + event->state, + buffer+len,nbytes-len, + NULL); + } + } + return len; + } + } + } + } +#endif + + /* We *should* use the new_mods (which does not contain any modifiers */ + /* that were used to compute the symbol here, but pre-XKB XLookupString */ + /* did not and we have to remain compatible. Sigh. */ + if ((dpy->xkb_info->flags&XkbLC_ConsumeLookupMods)==0) + new_mods= event->state; + + rtrnLen= XkbLookupKeyBinding(dpy,*keysym,new_mods,buffer,nbytes,NULL); + if (rtrnLen>0) + return rtrnLen; + + rtrnLen = XkbTranslateKeySym(dpy,keysym,new_mods,buffer,nbytes,NULL); + if ((event->state&ControlMask)&&(nbytes>0)&& + ((rtrnLen==0)||((rtrnLen==1)&&(buffer[0]>=' ')))&& + (XkbGroupForCoreState(event->state)!=XkbGroup1Index)&& + (dpy->xkb_info->xlib_ctrls&XkbLC_ControlFallback)) { + XKeyEvent tmp_ev; + tmp_ev= *event; + tmp_ev.state= XkbBuildCoreState(event->state,XkbGroup1Index); + return XLookupString (&tmp_ev, buffer, nbytes, keysym, status); + } + return rtrnLen; +} + + +int +#if NeedFunctionPrototypes +XkbLookupKeyBinding( Display * dpy, + register KeySym sym, + unsigned int mods, + char * buffer, + int nbytes, + int * extra_rtrn) +#else +XkbLookupKeyBinding(dpy, sym, mods, buffer, nbytes, extra_rtrn) + Display *dpy; + register KeySym sym; + unsigned int mods; + char *buffer; + int nbytes; + int * extra_rtrn; +#endif +{ + register struct _XKeytrans *p; + + if (extra_rtrn) + *extra_rtrn= 0; + for (p = dpy->key_bindings; p; p = p->next) { + if (((mods & AllMods) == p->state) && (sym == p->key)) { + int tmp = p->len; + if (tmp > nbytes) { + if (extra_rtrn) + *extra_rtrn= (tmp-nbytes); + tmp = nbytes; + } + memcpy (buffer, p->string, tmp); + if (tmp < nbytes) buffer[tmp]= '\0'; + return tmp; + } + } + return 0; +} + +char +#if NeedFunctionPrototypes +XkbToControl( char c ) +#else +XkbToControl( c ) + char c; +#endif +{ + 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; + return c; +} diff --git a/src/xkb/XKBCompat.c b/src/xkb/XKBCompat.c new file mode 100644 index 00000000..73c7d76d --- /dev/null +++ b/src/xkb/XKBCompat.c @@ -0,0 +1,277 @@ +/* $Xorg: XKBCompat.c,v 1.3 2000/08/17 19:45:00 cpqbld Exp $ */ +/************************************************************ +Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc. + +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 Silicon Graphics not be +used in advertising or publicity pertaining to distribution +of the software without specific prior written permission. +Silicon Graphics makes no representation about the suitability +of this software for any purpose. It is provided "as is" +without any express or implied warranty. + +SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS +SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON +GRAPHICS 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. + +********************************************************/ + +#include <stdio.h> +#define NEED_REPLIES +#define NEED_EVENTS +#define NEED_MAP_READERS +#include "Xlibint.h" +#include <X11/extensions/XKBproto.h> +#include "XKBlibint.h" + +Status +#if NeedFunctionPrototypes +_XkbReadGetCompatMapReply( Display * dpy, + xkbGetCompatMapReply * rep, + XkbDescPtr xkb, + int * nread_rtrn) +#else +_XkbReadGetCompatMapReply(dpy,rep,xkb,nread_rtrn) + Display * dpy; + xkbGetCompatMapReply * rep; + XkbDescPtr xkb; + int * nread_rtrn; +#endif +{ +register int i; +XkbReadBufferRec buf; + + if (!_XkbInitReadBuffer(dpy,&buf,(int)rep->length*4)) + return BadAlloc; + + if (nread_rtrn) + *nread_rtrn= (int)rep->length*4; + + i= rep->firstSI+rep->nSI; + if ((!xkb->compat)&& + (XkbAllocCompatMap(xkb,XkbAllCompatMask,i)!=Success)) + return BadAlloc; + + if (rep->nSI!=0) { + XkbSymInterpretRec *syms; + xkbSymInterpretWireDesc *wire; + + wire= (xkbSymInterpretWireDesc *)_XkbGetReadBufferPtr(&buf, + rep->nSI*SIZEOF(xkbSymInterpretWireDesc)); + if (wire==NULL) + goto BAILOUT; + syms= &xkb->compat->sym_interpret[rep->firstSI]; + + for (i=0;i<rep->nSI;i++,syms++,wire++) { + syms->sym= wire->sym; + syms->mods= wire->mods; + syms->match= wire->match; + syms->virtual_mod= wire->virtualMod; + syms->flags= wire->flags; + syms->act= *((XkbAnyAction *)&wire->act); + } + xkb->compat->num_si+= rep->nSI; + } + + if (rep->groups&XkbAllGroupsMask) { + register unsigned bit,nGroups; + xkbModsWireDesc * wire; + for (i=0,nGroups=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) { + if (rep->groups&bit) + nGroups++; + } + wire= (xkbModsWireDesc *)_XkbGetReadBufferPtr(&buf, + nGroups*SIZEOF(xkbModsWireDesc)); + if (wire==NULL) + goto BAILOUT; + for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) { + if ((rep->groups&bit)==0) + continue; + xkb->compat->groups[i].mask= wire->mask; + xkb->compat->groups[i].real_mods= wire->realMods; + xkb->compat->groups[i].vmods= wire->virtualMods; + wire++; + } + } + i= _XkbFreeReadBuffer(&buf); + if (i) + fprintf(stderr,"CompatMapReply! Bad length (%d extra bytes)\n",i); + if (i || buf.error) + return BadLength; + return Success; +BAILOUT: + _XkbFreeReadBuffer(&buf); + return BadLength; +} + +Status +#if NeedFunctionPrototypes +XkbGetCompatMap(Display *dpy,unsigned which,XkbDescPtr xkb) +#else +XkbGetCompatMap(dpy,which,xkb) + Display * dpy; + unsigned which; + XkbDescPtr xkb; +#endif +{ + register xkbGetCompatMapReq *req; + xkbGetCompatMapReply rep; + Status status; + XkbInfoPtr xkbi; + + if ( (!dpy) || (!xkb) || (dpy->flags & XlibDisplayNoXkb) || + ((xkb->dpy!=NULL)&&(xkb->dpy!=dpy)) || + (!dpy->xkb_info && (!XkbUseExtension(dpy,NULL,NULL)))) + return BadAccess; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbGetCompatMap, req); + req->reqType = xkbi->codes->major_opcode; + req->xkbReqType = X_kbGetCompatMap; + req->deviceSpec = xkb->device_spec; + if (which&XkbSymInterpMask) + req->getAllSI= True; + else req->getAllSI= False; + req->firstSI= req->nSI= 0; + + if (which&XkbGroupCompatMask) + req->groups= XkbAllGroupsMask; + else req->groups= 0; + + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return BadLength; + } + if (xkb->dpy==NULL) + xkb->dpy= dpy; + if (xkb->device_spec==XkbUseCoreKbd) + xkb->device_spec= rep.deviceID; + + status = _XkbReadGetCompatMapReply(dpy,&rep,xkb,NULL); + UnlockDisplay(dpy); + SyncHandle(); + return status; +} + +static Bool +#if NeedFunctionPrototypes +_XkbWriteSetCompatMap(Display *dpy,xkbSetCompatMapReq *req,XkbDescPtr xkb) +#else +_XkbWriteSetCompatMap(dpy,req,xkb) + Display * dpy; + xkbSetCompatMapReq *req; + XkbDescPtr xkb; +#endif +{ +CARD16 firstSI; +CARD16 nSI; +int size; +register int i,nGroups; +register unsigned bit; +unsigned groups; +char * buf; + + firstSI = req->firstSI; + nSI = req->nSI; + size= nSI*SIZEOF(xkbSymInterpretWireDesc); + nGroups= 0; + groups= req->groups; + if (groups&XkbAllGroupsMask) { + for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) { + if (groups&bit) + nGroups++; + } + size+= SIZEOF(xkbModsWireDesc)*nGroups; + } + req->length+= size/4; + BufAlloc(char *,buf,size); + if (!buf) + return False; + + if (nSI) { + XkbSymInterpretPtr sym= &xkb->compat->sym_interpret[firstSI]; + xkbSymInterpretWireDesc *wire= (xkbSymInterpretWireDesc *)buf; + for (i=0;i<nSI;i++,wire++,sym++) { + wire->sym= (CARD32)sym->sym; + wire->mods= sym->mods; + wire->match= sym->match; + wire->flags= sym->flags; + wire->virtualMod= sym->virtual_mod; + memcpy(&wire->act,&sym->act,sz_xkbActionWireDesc); + } + buf+= nSI*SIZEOF(xkbSymInterpretWireDesc); + } + if (groups&XkbAllGroupsMask) { + xkbModsWireDesc * out; + + out= (xkbModsWireDesc *)buf; + for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) { + if ((groups&bit)!=0) { + out->mask= xkb->compat->groups[i].mask; + out->realMods= xkb->compat->groups[i].real_mods; + out->virtualMods= xkb->compat->groups[i].vmods; + out++; + } + } + buf+= nGroups*SIZEOF(xkbModsWireDesc); + } + return True; +} + +Bool +#if NeedFunctionPrototypes +XkbSetCompatMap(Display *dpy,unsigned which,XkbDescPtr xkb,Bool updateActions) +#else +XkbSetCompatMap(dpy,which,xkb,updateActions) + Display * dpy; + unsigned which; + XkbDescPtr xkb; + Bool updateActions; +#endif +{ + register xkbSetCompatMapReq *req; + Status ok; + XkbInfoPtr xkbi; + + if ((dpy->flags & XlibDisplayNoXkb) || (dpy!=xkb->dpy) || + (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) + return False; + if ((!xkb->compat) || + ((which&XkbSymInterpMask)&&(!xkb->compat->sym_interpret))) + return False; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbSetCompatMap, req); + req->reqType = xkbi->codes->major_opcode; + req->xkbReqType = X_kbSetCompatMap; + req->deviceSpec = xkb->device_spec; + req->recomputeActions = updateActions; + if (which&XkbSymInterpMask) { + req->truncateSI = True; + req->firstSI= 0; + req->nSI= xkb->compat->num_si; + } + else { + req->truncateSI = False; + req->firstSI= 0; + req->nSI= 0; + } + if (which&XkbGroupCompatMask) + req->groups= XkbAllGroupsMask; + else req->groups= 0; + ok= _XkbWriteSetCompatMap(dpy,req,xkb); + UnlockDisplay(dpy); + SyncHandle(); + return ok; +} + diff --git a/src/xkb/XKBCtrls.c b/src/xkb/XKBCtrls.c new file mode 100644 index 00000000..2e08e50e --- /dev/null +++ b/src/xkb/XKBCtrls.c @@ -0,0 +1,418 @@ +/* $Xorg: XKBCtrls.c,v 1.3 2000/08/17 19:45:00 cpqbld Exp $ */ +/************************************************************ +Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc. + +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 Silicon Graphics not be +used in advertising or publicity pertaining to distribution +of the software without specific prior written permission. +Silicon Graphics makes no representation about the suitability +of this software for any purpose. It is provided "as is" +without any express or implied warranty. + +SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS +SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON +GRAPHICS 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. + +********************************************************/ + +#include <stdio.h> +#define NEED_REPLIES +#define NEED_EVENTS +#include "Xlibint.h" +#include <X11/extensions/XKBproto.h> +#include "XKBlibint.h" + + +static xkbSetControlsReq * +#if NeedFunctionPrototypes +_XkbGetSetControlsReq(Display *dpy,XkbInfoPtr xkbi,unsigned int deviceSpec) +#else +_XkbGetSetControlsReq(dpy,xkbi,deviceSpec) + Display * dpy; + XkbInfoPtr xkbi; + unsigned int deviceSpec; +#endif +{ +xkbSetControlsReq *req; + + GetReq(kbSetControls,req); + bzero(req,SIZEOF(xkbSetControlsReq)); + req->reqType = xkbi->codes->major_opcode; + req->length = (SIZEOF(xkbSetControlsReq)>>2); + req->xkbReqType = X_kbSetControls; + req->deviceSpec = deviceSpec; + return req; +} + +Bool +#if NeedFunctionPrototypes +XkbSetAutoRepeatRate( Display *dpy, + unsigned int deviceSpec, + unsigned int timeout, + unsigned int interval) +#else +XkbSetAutoRepeatRate(dpy, deviceSpec, timeout, interval) + Display *dpy; + unsigned int deviceSpec; + unsigned int timeout; + unsigned int interval; +#endif +{ + register xkbSetControlsReq *req; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) + return False; + LockDisplay(dpy); + req= _XkbGetSetControlsReq(dpy,dpy->xkb_info,deviceSpec); + req->changeCtrls = XkbRepeatKeysMask; + req->repeatDelay = timeout; + req->repeatInterval = interval; + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + +Bool +#if NeedFunctionPrototypes +XkbGetAutoRepeatRate( Display * dpy, + unsigned int deviceSpec, + unsigned int * timeoutp, + unsigned int * intervalp) +#else +XkbGetAutoRepeatRate(dpy, deviceSpec, timeoutp, intervalp) + Display *dpy; + unsigned int deviceSpec; + unsigned int *timeoutp; + unsigned int *intervalp; +#endif +{ + register xkbGetControlsReq *req; + xkbGetControlsReply rep; + XkbInfoPtr xkbi; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) + return False; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbGetControls, req); + req->reqType = xkbi->codes->major_opcode; + req->xkbReqType = X_kbGetControls; + req->deviceSpec = deviceSpec; + if (!_XReply(dpy, (xReply *)&rep, + (SIZEOF(xkbGetControlsReply)-SIZEOF(xReply))>>2, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + UnlockDisplay(dpy); + SyncHandle(); + *timeoutp = rep.repeatDelay; + *intervalp = rep.repeatInterval; + return True; +} + +Bool +#if NeedFunctionPrototypes +XkbSetServerInternalMods( Display * dpy, + unsigned deviceSpec, + unsigned affectReal, + unsigned realValues, + unsigned affectVirtual, + unsigned virtualValues) +#else +XkbSetServerInternalMods(dpy,deviceSpec, + affectReal,realValues,affectVirtual,virtualValues) + Display *dpy; + unsigned deviceSpec; + unsigned affectReal; + unsigned realValues; + unsigned affectVirtual; + unsigned virtualValues; +#endif +{ + register xkbSetControlsReq *req; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) + return False; + LockDisplay(dpy); + req= _XkbGetSetControlsReq(dpy,dpy->xkb_info,deviceSpec); + req->affectInternalMods = affectReal; + req->internalMods = realValues; + req->affectInternalVMods= affectVirtual; + req->internalVMods= virtualValues; + req->changeCtrls = XkbInternalModsMask; + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + +Bool +#if NeedFunctionPrototypes +XkbSetIgnoreLockMods( Display * dpy, + unsigned int deviceSpec, + unsigned affectReal, + unsigned realValues, + unsigned affectVirtual, + unsigned virtualValues) +#else +XkbSetIgnoreLockMods(dpy,deviceSpec, + affectReal,realValues,affectVirtual,virtualValues) + Display *dpy; + unsigned int deviceSpec; + unsigned affectReal; + unsigned realValues; + unsigned affectVirtual; + unsigned virtualValues; +#endif +{ + register xkbSetControlsReq *req; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) + return False; + LockDisplay(dpy); + req= _XkbGetSetControlsReq(dpy,dpy->xkb_info,deviceSpec); + req->affectIgnoreLockMods= affectReal; + req->ignoreLockMods = realValues; + req->affectIgnoreLockVMods= affectVirtual; + req->ignoreLockVMods= virtualValues; + req->changeCtrls = XkbIgnoreLockModsMask; + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + +Bool +#if NeedFunctionPrototypes +XkbChangeEnabledControls( Display * dpy, + unsigned deviceSpec, + unsigned affect, + unsigned values) +#else +XkbChangeEnabledControls(dpy,deviceSpec,affect,values) + Display * dpy; + unsigned deviceSpec; + unsigned affect; + unsigned values; +#endif +{ + register xkbSetControlsReq *req; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) + return False; + LockDisplay(dpy); + req= _XkbGetSetControlsReq(dpy,dpy->xkb_info,deviceSpec); + req->affectEnabledCtrls= affect; + req->enabledCtrls= (affect&values); + req->changeCtrls = XkbControlsEnabledMask; + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + +Status +#if NeedFunctionPrototypes +XkbGetControls(Display *dpy, unsigned long which, XkbDescPtr xkb) +#else +XkbGetControls(dpy, which, xkb) + Display *dpy; + unsigned long which; + XkbDescPtr xkb; +#endif +{ + register xkbGetControlsReq *req; + xkbGetControlsReply rep; + XkbControlsPtr ctrls; + XkbInfoPtr xkbi; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) + return BadAccess; + if ((!xkb) || (!which)) + return BadMatch; + + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbGetControls, req); + if (!xkb->ctrls) { + xkb->ctrls = _XkbTypedCalloc(1,XkbControlsRec); + if (!xkb->ctrls) { + UnlockDisplay(dpy); + SyncHandle(); + return BadAlloc; + } + } + req->reqType = xkbi->codes->major_opcode; + req->xkbReqType = X_kbGetControls; + req->deviceSpec = xkb->device_spec; + if (!_XReply(dpy, (xReply *)&rep, + (SIZEOF(xkbGetControlsReply)-SIZEOF(xReply))>>2, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return BadImplementation; + } + if (xkb->device_spec==XkbUseCoreKbd) + xkb->device_spec= rep.deviceID; + ctrls= xkb->ctrls; + if (which&XkbControlsEnabledMask) + ctrls->enabled_ctrls = rep.enabledCtrls; + ctrls->num_groups= rep.numGroups; + if (which&XkbGroupsWrapMask) + ctrls->groups_wrap= rep.groupsWrap; + if (which&XkbInternalModsMask) { + ctrls->internal.mask = rep.internalMods; + ctrls->internal.real_mods = rep.internalRealMods; + ctrls->internal.vmods = rep.internalVMods; + } + if (which&XkbIgnoreLockModsMask) { + ctrls->ignore_lock.mask = rep.ignoreLockMods; + ctrls->ignore_lock.real_mods = rep.ignoreLockRealMods; + ctrls->ignore_lock.vmods = rep.ignoreLockVMods; + } + if (which&XkbRepeatKeysMask) { + ctrls->repeat_delay = rep.repeatDelay; + ctrls->repeat_interval = rep.repeatInterval; + } + if (which&XkbSlowKeysMask) + ctrls->slow_keys_delay = rep.slowKeysDelay; + if (which&XkbBounceKeysMask) + ctrls->debounce_delay = rep.debounceDelay; + if (which&XkbMouseKeysMask) { + ctrls->mk_dflt_btn = rep.mkDfltBtn; + } + if (which&XkbMouseKeysAccelMask) { + ctrls->mk_delay = rep.mkDelay; + ctrls->mk_interval = rep.mkInterval; + ctrls->mk_time_to_max = rep.mkTimeToMax; + ctrls->mk_max_speed = rep.mkMaxSpeed; + ctrls->mk_curve = rep.mkCurve; + } + if (which&XkbAccessXKeysMask) + ctrls->ax_options= rep.axOptions; + if (which&XkbAccessXTimeoutMask) { + ctrls->ax_timeout = rep.axTimeout; + ctrls->axt_ctrls_mask = rep.axtCtrlsMask; + ctrls->axt_ctrls_values = rep.axtCtrlsValues; + ctrls->axt_opts_mask = rep.axtOptsMask; + ctrls->axt_opts_values= rep.axtOptsValues; + } + if (which&XkbPerKeyRepeatMask) { + memcpy(ctrls->per_key_repeat,rep.perKeyRepeat, + XkbPerKeyBitArraySize); + } + UnlockDisplay(dpy); + SyncHandle(); + return Success; +} + +Bool +#if NeedFunctionPrototypes +XkbSetControls(Display *dpy, unsigned long which, XkbDescPtr xkb) +#else +XkbSetControls(dpy, which, xkb) + Display * dpy; + unsigned long which; + XkbDescPtr xkb; +#endif +{ + register xkbSetControlsReq *req; + XkbControlsPtr ctrls; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) + return False; + if ((!xkb)||(!xkb->ctrls)) + return False; + + ctrls= xkb->ctrls; + LockDisplay(dpy); + req= _XkbGetSetControlsReq(dpy,dpy->xkb_info,xkb->device_spec); + req->changeCtrls = (CARD32)which; + if (which&XkbInternalModsMask) { + req->affectInternalMods= ~0; + req->internalMods= ctrls->internal.real_mods; + req->affectInternalVMods = ~0; + req->internalVMods= ctrls->internal.vmods; + } + if (which&XkbIgnoreLockModsMask) { + req->affectIgnoreLockMods= ~0; + req->ignoreLockMods= ctrls->ignore_lock.real_mods; + req->affectIgnoreLockVMods= ~0; + req->ignoreLockVMods= ctrls->ignore_lock.vmods; + } + if (which&XkbControlsEnabledMask) { + req->affectEnabledCtrls= XkbAllBooleanCtrlsMask; + req->enabledCtrls= ctrls->enabled_ctrls; + } + if (which&XkbRepeatKeysMask) { + req->repeatDelay = ctrls->repeat_delay; + req->repeatInterval = ctrls->repeat_interval; + } + if (which&XkbSlowKeysMask) + req->slowKeysDelay = ctrls->slow_keys_delay; + if (which&XkbBounceKeysMask) + req->debounceDelay = ctrls->debounce_delay; + if (which&XkbMouseKeysMask) { + req->mkDfltBtn = ctrls->mk_dflt_btn; + } + if (which&XkbGroupsWrapMask) + req->groupsWrap= ctrls->groups_wrap; + if (which&(XkbAccessXKeysMask|XkbStickyKeysMask|XkbAccessXFeedbackMask)) + req->axOptions= ctrls->ax_options; + if (which&XkbMouseKeysAccelMask) { + req->mkDelay = ctrls->mk_delay; + req->mkInterval = ctrls->mk_interval; + req->mkTimeToMax = ctrls->mk_time_to_max; + req->mkMaxSpeed = ctrls->mk_max_speed; + req->mkCurve = ctrls->mk_curve; + } + if (which&XkbAccessXTimeoutMask) { + req->axTimeout = ctrls->ax_timeout; + req->axtCtrlsMask = ctrls->axt_ctrls_mask; + req->axtCtrlsValues = ctrls->axt_ctrls_values; + req->axtOptsMask = ctrls->axt_opts_mask; + req->axtOptsValues=ctrls->axt_opts_values; + } + if (which&XkbPerKeyRepeatMask) { + memcpy(req->perKeyRepeat,ctrls->per_key_repeat, + XkbPerKeyBitArraySize); + } + UnlockDisplay(dpy); + SyncHandle(); + return False; +} + +/***====================================================================***/ + +void +#if NeedFunctionPrototypes +XkbNoteControlsChanges( XkbControlsChangesPtr old, + XkbControlsNotifyEvent * new, + unsigned int wanted) +#else +XkbNoteControlsChanges(old,new,wanted) + XkbControlsChangesPtr old; + XkbControlsNotifyEvent * new; + unsigned int wanted; +#endif +{ + old->changed_ctrls|= (new->changed_ctrls&wanted); + if (new->changed_ctrls&XkbControlsEnabledMask&wanted) + old->enabled_ctrls_changes^= new->enabled_ctrl_changes; + /* num_groups_changed?? */ + return; +} diff --git a/src/xkb/XKBCvt.c b/src/xkb/XKBCvt.c new file mode 100644 index 00000000..bd965d24 --- /dev/null +++ b/src/xkb/XKBCvt.c @@ -0,0 +1,642 @@ +/* $Xorg: XKBCvt.c,v 1.5 2001/02/09 02:03:38 xorgcvs Exp $ */ +/* + +Copyright 1988, 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. + +*/ + +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> + +#include <X11/X.h> +#include <X11/Xlib.h> +#define NEED_EVENTS +#include "Xlibint.h" +#include "Xlcint.h" +#include "XlcPubI.h" +#include <X11/Xutil.h> +#include <X11/Xmd.h> +#define XK_LATIN1 +#define XK_PUBLISHING +#include <X11/keysym.h> +#include <X11/extensions/XKBproto.h> +#include "XKBlibint.h" +#include <X11/Xlocale.h> +#include <ctype.h> +#include <X11/Xos.h> + +#ifdef __sgi_not_xconsortium +#define XKB_EXTEND_LOOKUP_STRING +#endif + +#ifdef X_NOT_STDC_ENV +extern char *getenv(); +#endif + +#ifdef __STDC__ +#define Const const +#else +#define Const /**/ +#endif +#if defined(__STDC__) && !defined(NORCONST) +#define RConst const +#else +#define RConst /**/ +#endif + +/* bit (1<<i) means character is in codeset i at the same codepoint */ +extern unsigned int _Xlatin1[]; + +/* bit (1<<i) means character is in codeset i at the same codepoint */ +extern unsigned int _Xlatin2[]; + +/* maps Cyrillic keysyms to KOI8-R */ +extern unsigned char _Xkoi8[]; + +extern unsigned short _Xkoi8_size; + +#define sLatin1 0 +#define sLatin2 1 +#define sLatin3 2 +#define sLatin4 3 +#define sKana 4 +#define sX0201 0x01000004 +#define sArabic 5 +#define sCyrillic 6 +#define sGreek 7 +#define sAPL 11 +#define sHebrew 12 +#define sThai 13 +#define sKorean 14 +#define sLatin5 15 +#define sLatin6 16 +#define sLatin7 17 +#define sLatin8 18 +#define sLatin9 19 +#define sCurrency 32 + + +static unsigned long WantLatin1 = sLatin1; +static unsigned long WantLatin2 = sLatin2; +static unsigned long WantLatin3 = sLatin3; +static unsigned long WantLatin4 = sLatin4; +static unsigned long WantLatin5 = sLatin5; +static unsigned long WantLatin6 = sLatin6; +static unsigned long WantKana = sKana; +static unsigned long WantX0201 = sX0201; +static unsigned long WantArabic = sArabic; +static unsigned long WantCyrillic = sCyrillic; +static unsigned long WantGreek = sGreek; +static unsigned long WantAPL = sAPL; +static unsigned long WantHebrew = sHebrew; + +static int +#if NeedFunctionPrototypes +_XkbHandleSpecialSym(KeySym keysym, char *buffer, int nbytes, int *extra_rtrn) +#else +_XkbHandleSpecialSym(keysym, buffer, nbytes, extra_rtrn) + KeySym keysym; + char *buffer; + int nbytes; + int * extra_rtrn; +#endif +{ + + /* try to convert to Latin-1, handling ctrl */ + if (!(((keysym >= XK_BackSpace) && (keysym <= XK_Clear)) || + (keysym == XK_Return) || (keysym == XK_Escape) || + (keysym == XK_KP_Space) || (keysym == XK_KP_Tab) || + (keysym == XK_KP_Enter) || + ((keysym >= XK_KP_Multiply) && (keysym <= XK_KP_9)) || + (keysym == XK_KP_Equal) || + (keysym == XK_Delete))) + return 0; + + if (nbytes<1) { + if (extra_rtrn) + *extra_rtrn= 1; + return 0; + } + /* if X keysym, convert to ascii by grabbing low 7 bits */ + if (keysym == XK_KP_Space) + buffer[0] = XK_space & 0x7F; /* patch encoding botch */ + else if (keysym == XK_hyphen) + buffer[0] = (char)(XK_minus & 0xFF); /* map to equiv character */ + else buffer[0] = (char)(keysym & 0x7F); + return 1; +} + +extern int +_XGetCharCode ( +#if NeedFunctionPrototypes + unsigned long, KeySym, char*, int +#endif +); + +/*ARGSUSED*/ +int +#if NeedFunctionPrototypes +_XkbKSToKnownSet ( XPointer priv, + KeySym keysym, + char * buffer, + int nbytes, + int * extra_rtrn) +#else +_XkbKSToKnownSet (priv, keysym, buffer, nbytes, extra_rtrn) + XPointer priv; + KeySym keysym; + char *buffer; + int nbytes; + int *extra_rtrn; +#endif +{ + unsigned long kset,keysymSet; + int count,isLatin1; + char tbuf[8],*buf; + + if (extra_rtrn) + *extra_rtrn= 0; + + keysymSet = *((unsigned long *)priv); + kset = keysymSet&0xffffff; + + /* convert "dead" diacriticals for dumb applications */ + if ( (keysym&0xffffff00)== 0xfe00 ) { + switch ( keysym ) { + case XK_dead_grave: keysym = XK_grave; break; + case XK_dead_acute: keysym = XK_acute; break; + case XK_dead_circumflex: keysym = XK_asciicircum; break; + case XK_dead_tilde: keysym = XK_asciitilde; break; + case XK_dead_macron: keysym = XK_macron; break; + case XK_dead_breve: keysym = XK_breve; break; + case XK_dead_abovedot: keysym = XK_abovedot; break; + case XK_dead_diaeresis: keysym = XK_diaeresis; break; + case XK_dead_abovering: keysym = XK_degree; break; + case XK_dead_doubleacute: keysym = XK_doubleacute; break; + case XK_dead_caron: keysym = XK_caron; break; + case XK_dead_cedilla: keysym = XK_cedilla; break; + case XK_dead_ogonek : keysym = XK_ogonek; break; + case XK_dead_iota: keysym = XK_Greek_iota; break; +#ifdef XK_KATAKANA + case XK_dead_voiced_sound: keysym = XK_voicedsound; break; + case XK_dead_semivoiced_sound:keysym = XK_semivoicedsound; break; +#endif + } + } + + isLatin1 = ((keysym&0xffffff00)==0); + count = 0; + + if (nbytes<1) buf= tbuf; + else buf= buffer; + + if ((keysym&0xffffff00)==0xff00) { + return _XkbHandleSpecialSym(keysym, buf, nbytes, extra_rtrn); + } + return _XGetCharCode (keysymSet, keysym, buf, nbytes); +} + +typedef struct _XkbToKS { + unsigned prefix; + char *map; +} XkbToKS; + +/*ARGSUSED*/ +static KeySym +#if NeedFunctionPrototypes +_XkbKnownSetToKS(XPointer priv,char *buffer,int nbytes,Status *status) +#else +_XkbKnownSetToKS(priv,buffer,nbytes,status) + XPointer priv; + char *buffer; + int nbytes; + Status *status; +#endif +{ + if (nbytes!=1) + return NoSymbol; + if (((buffer[0]&0x80)==0)&&(buffer[0]>=32)) + return buffer[0]; + else if ((buffer[0]&0x7f)>=32) { + XkbToKS *map= (XkbToKS *)priv; + if ( map ) { + if ( map->map ) return map->prefix|map->map[buffer[0]&0x7f]; + else return map->prefix|buffer[0]; + } + return buffer[0]; + } + return NoSymbol; +} + +/*ARGSUSED*/ +int +#if NeedFunctionPrototypes +_XkbKSToThai ( XPointer priv, + KeySym keysym, + char * buffer, + int nbytes, + int * extra_rtrn) +#else +_XkbKSToThai (priv, keysym, buffer, nbytes, extra_rtrn) + XPointer priv; + KeySym keysym; + char *buffer; + int nbytes; + int *extra_rtrn; +#endif +{ + + if ((keysym&0xffffff00)==0xff00) { + return _XkbHandleSpecialSym(keysym, buffer, nbytes, extra_rtrn); + } + else if (((keysym&0xffffff80)==0xd80)||((keysym&0xffffff80)==0)) { + if (nbytes>0) { + buffer[0]= (char)(keysym&0xff); + if (nbytes>1) + buffer[1]= '\0'; + return 1; + } + if (extra_rtrn) + *extra_rtrn= 1; + } + return 0; +} + +/*ARGSUSED*/ +static KeySym +#if NeedFunctionPrototypes +_XkbThaiToKS(XPointer priv,char *buffer,int nbytes,Status *status) +#else +_XkbThaiToKS(priv,buffer,nbytes,status) + XPointer priv; + char *buffer; + int nbytes; + Status *status; +#endif +{ + if (nbytes!=1) + return NoSymbol; + if (((buffer[0]&0x80)==0)&&(buffer[0]>=32)) + return buffer[0]; + else if ((buffer[0]&0x7f)>=32) { + return 0xd00|buffer[0]; + } + return NoSymbol; +} + +static KeySym +#if NeedFunctionPrototypes +__XkbDefaultToUpper(KeySym sym) +#else +__XkbDefaultToUpper(sym) + KeySym sym; +#endif +{ + KeySym lower,upper; + + XConvertCase(sym, &lower, &upper); + return upper; +} + +int _XkbKSToKoi8 (priv, keysym, buffer, nbytes, status) + XPointer priv; + KeySym keysym; + char *buffer; + int nbytes; + Status *status; +{ + if ((keysym&0xffffff00)==0xff00) { + return _XkbHandleSpecialSym(keysym, buffer, nbytes, status); + } + else if (((keysym&0xffffff80)==0x680)||((keysym&0xffffff80)==0)) { + if (nbytes>0) { + if ( (keysym&0x80)==0 ) + buffer[0] = keysym&0x7f; + else buffer[0] = _Xkoi8[keysym & 0x7f]; + if (nbytes>1) + buffer[1]= '\0'; + return 1; + } + } + return 0; +} + +static KeySym +_XkbKoi8ToKS(priv,buffer,nbytes,status) + XPointer priv; + char *buffer; + int nbytes; + Status *status; +{ + if (nbytes!=1) + return NoSymbol; + if (((buffer[0]&0x80)==0)&&(buffer[0]>=32)) + return buffer[0]; + else if ((buffer[0]&0x7f)>=32) { + register int i; + for (i=0;i<_Xkoi8_size;i++) { + if (_Xkoi8[i]==buffer[0]) + return 0x680|i; + } + } + return NoSymbol; +} + +/***====================================================================***/ + + +static XkbConverters RConst cvt_ascii = { + _XkbKSToKnownSet,(XPointer)&WantLatin1,_XkbKnownSetToKS,NULL,__XkbDefaultToUpper +}; + +static XkbConverters RConst cvt_latin1 = { + _XkbKSToKnownSet,(XPointer)&WantLatin1,_XkbKnownSetToKS,NULL,NULL +}; + +static XkbConverters RConst cvt_latin2 = { + _XkbKSToKnownSet,(XPointer)&WantLatin2,_XkbKnownSetToKS,NULL,NULL +}; + +static XkbConverters RConst cvt_latin3 = { + _XkbKSToKnownSet,(XPointer)&WantLatin3,_XkbKnownSetToKS,NULL,NULL +}; + +static XkbConverters RConst cvt_latin4 = { + _XkbKSToKnownSet,(XPointer)&WantLatin4,_XkbKnownSetToKS,NULL,NULL +}; + +static XkbConverters RConst cvt_latin5 = { + _XkbKSToKnownSet,(XPointer)&WantLatin5,_XkbKnownSetToKS,NULL,NULL +}; + +static XkbConverters RConst cvt_latin6 = { + _XkbKSToKnownSet,(XPointer)&WantLatin6,_XkbKnownSetToKS,NULL,NULL +}; + +static XkbConverters RConst cvt_kana = { + _XkbKSToKnownSet,(XPointer)&WantKana,_XkbKnownSetToKS,NULL,NULL +}; + +static XkbConverters RConst cvt_X0201 = { + _XkbKSToKnownSet,(XPointer)&WantX0201,_XkbKnownSetToKS,NULL,NULL +}; + +static XkbConverters RConst cvt_Arabic = { + _XkbKSToKnownSet,(XPointer)&WantArabic,_XkbKnownSetToKS,NULL,NULL +}; + +static XkbConverters RConst cvt_Cyrillic = { + _XkbKSToKnownSet,(XPointer)&WantCyrillic,_XkbKnownSetToKS,NULL,NULL +}; + +static XkbConverters RConst cvt_Greek = { + _XkbKSToKnownSet,(XPointer)&WantGreek,_XkbKnownSetToKS,NULL,NULL +}; + +static XkbConverters RConst cvt_APL = { + _XkbKSToKnownSet,(XPointer)&WantAPL,_XkbKnownSetToKS,NULL,NULL +}; + +static XkbConverters RConst cvt_Hebrew = { + _XkbKSToKnownSet,(XPointer)&WantHebrew,_XkbKnownSetToKS,NULL,NULL +}; + +static XkbConverters cvt_Thai = { + _XkbKSToThai, NULL, _XkbThaiToKS, NULL, NULL +}; + +static XkbConverters cvt_Koi8 = { + _XkbKSToKoi8, NULL, _XkbKoi8ToKS, NULL, NULL +}; + +static int +#if NeedFunctionPrototypes +Strcmp(char *str1, char *str2) +#else +Strcmp(str1, str2) + char *str1, *str2; +#endif +{ + char str[256]; + char c, *s; + + if (strlen (str1) >= sizeof str) /* almost certain it's a mismatch */ + return 1; + + for (s = str; (c = *str1++); ) { + if (isupper(c)) + c = tolower(c); + *s++ = c; + } + *s = '\0'; + return (strcmp(str, str2)); +} + +int +#if NeedFunctionPrototypes +_XkbGetConverters(char *encoding_name, XkbConverters *cvt_rtrn) +#else +_XkbGetConverters(encoding_name, cvt_rtrn) + char *encoding_name; + XkbConverters *cvt_rtrn; +#endif +{ + if ( cvt_rtrn ) { + if ( (encoding_name==NULL) || + (Strcmp(encoding_name,"ascii")==0) || + (Strcmp(encoding_name,"string")==0) ) + *cvt_rtrn = cvt_ascii; + else if (Strcmp(encoding_name,"iso8859-1")==0) + *cvt_rtrn = cvt_latin1; + else if (Strcmp(encoding_name, "iso8859-2")==0) + *cvt_rtrn = cvt_latin2; + else if (Strcmp(encoding_name, "iso8859-3")==0) + *cvt_rtrn = cvt_latin3; + else if (Strcmp(encoding_name, "iso8859-4")==0) + *cvt_rtrn = cvt_latin4; + else if (Strcmp(encoding_name, "iso8859-5")==0) + *cvt_rtrn = cvt_Cyrillic; + else if (Strcmp(encoding_name, "iso8859-6")==0) + *cvt_rtrn = cvt_Arabic; + else if (Strcmp(encoding_name, "iso8859-7")==0) + *cvt_rtrn = cvt_Greek; + else if (Strcmp(encoding_name, "iso8859-8")==0) + *cvt_rtrn = cvt_Hebrew; + else if (Strcmp(encoding_name, "iso8859-9")==0) + *cvt_rtrn = cvt_latin5; + else if (Strcmp(encoding_name, "iso8859-10")==0) + *cvt_rtrn = cvt_latin6; + else if (Strcmp(encoding_name, "apl")==0) + *cvt_rtrn = cvt_APL; +#if 0 + else if (Strcmp(encoding_name, "ja.euc")==0) + *cvt_rtrn = ???; + else if (Strcmp(encoding_name, "ja.jis")==0) + *cvt_rtrn = ???; + else if (Strcmp(encoding_name, "ja.sjis")==0) + *cvt_rtrn = ???; +#endif + else if (Strcmp(encoding_name, "jisx0201")==0) /* ??? */ + *cvt_rtrn = cvt_X0201; + else if (Strcmp(encoding_name, "kana")==0) /* ??? */ + *cvt_rtrn = cvt_kana; + else if ((Strcmp(encoding_name, "tactis")==0) || + (Strcmp(encoding_name, "tis620.2533-1")==0)) + *cvt_rtrn = cvt_Thai; + else if (Strcmp(encoding_name, "koi8-r")==0) + *cvt_rtrn = cvt_Koi8; + /* other codesets go here */ + else *cvt_rtrn = cvt_latin1; + return 1; + } + *cvt_rtrn= cvt_latin1; + return 1; +} + +/***====================================================================***/ + +/* + * The function _XkbGetCharset seems to be missnamed as what it seems to + * be used for is to determine the encoding-name for the locale. ??? + */ + +#ifdef XKB_EXTEND_LOOKUP_STRING + +/* + * XKB_EXTEND_LOOKUP_STRING is not used by the SI. It is used by various + * X Consortium/X Project Team members, so we leave it in the source as + * an simplify integration by these companies. + */ + +#define CHARSET_FILE "/usr/lib/X11/input/charsets" +static char *_XkbKnownLanguages = "c=ascii:da,de,en,es,fi,fr,is,it,nl,no,pt,sv=iso8859-1:hu,pl,cs=iso8859-2:bg,ru=iso8859-5:ar,ara=iso8859-6:el=iso8859-7:th,th_TH,th_TH.TACTIS=tactis"; + +char * +_XkbGetCharset() +{ + /* + * PAGE USAGE TUNING: explicitly initialize to move these to data + * instead of bss + */ + static char buf[100] = { 0 }; + char lang[256]; + char *start,*tmp,*end,*next,*set; + char *country,*charset; + char *locale; + + tmp = getenv( "_XKB_CHARSET" ); + if ( tmp ) + return tmp; + locale = setlocale(LC_CTYPE,NULL); + + if ( locale == NULL ) + return NULL; + + for (tmp = lang; *tmp = *locale++; tmp++) { + if (isupper(*tmp)) + *tmp = tolower(*tmp); + } + country = strchr( lang, '_'); + if ( country ) { + *country++ = '\0'; + charset = strchr( country, '.' ); + if ( charset ) *charset++ = '\0'; + if ( charset ) { + strncpy(buf,charset,99); + buf[99] = '\0'; + return buf; + } + } + else { + charset = NULL; + } + + if ((tmp = getenv("_XKB_LOCALE_CHARSETS"))!=NULL) { + start = _XkbAlloc(strlen(tmp) + 1); + strcpy(start, tmp); + tmp = start; + } else { + struct stat sbuf; + FILE *file; + if ( (stat(CHARSET_FILE,&sbuf)==0) && (sbuf.st_mode&S_IFREG) && + (file = fopen(CHARSET_FILE,"r")) ) { + tmp = _XkbAlloc(sbuf.st_size+1); + if (tmp!=NULL) { + sbuf.st_size = (long)fread(tmp,1,sbuf.st_size,file); + tmp[sbuf.st_size] = '\0'; + } + fclose(file); + } + } + + if ( tmp == NULL ) { + tmp = _XkbAlloc(strlen(_XkbKnownLanguages) + 1); + if (!tmp) + return NULL; + strcpy(tmp, _XkbKnownLanguages); + } + start = tmp; + do { + if ( (set=strchr(tmp,'=')) == NULL ) + break; + *set++ = '\0'; + if ( (next=strchr(set,':')) != NULL ) + *next++ = '\0'; + while ( tmp && *tmp ) { + if ( (end=strchr(tmp,',')) != NULL ) + *end++ = '\0'; + if ( Strcmp( tmp, lang ) == 0 ) { + strncpy(buf,set,100); + buf[99] = '\0'; + Xfree(start); + return buf; + } + tmp = end; + } + tmp = next; + } while ( tmp && *tmp ); + Xfree(start); + return NULL; +} +#else +char * +_XkbGetCharset() +{ + char *tmp; + XLCd lcd; + + tmp = getenv( "_XKB_CHARSET" ); + if ( tmp ) + return tmp; + + lcd = _XlcCurrentLC(); + if ( lcd ) + return XLC_PUBLIC(lcd,encoding_name); + + return NULL; +} +#endif + diff --git a/src/xkb/XKBExtDev.c b/src/xkb/XKBExtDev.c new file mode 100644 index 00000000..c4d99681 --- /dev/null +++ b/src/xkb/XKBExtDev.c @@ -0,0 +1,953 @@ +/* $Xorg: XKBExtDev.c,v 1.3 2000/08/17 19:45:01 cpqbld Exp $ */ +/************************************************************ +Copyright (c) 1995 by Silicon Graphics Computer Systems, Inc. + +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 Silicon Graphics not be +used in advertising or publicity pertaining to distribution +of the software without specific prior written permission. +Silicon Graphics makes no representation about the suitability +of this software for any purpose. It is provided "as is" +without any express or implied warranty. + +SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS +SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON +GRAPHICS 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. + +********************************************************/ + +#include <stdio.h> +#define NEED_REPLIES +#define NEED_EVENTS +#define NEED_MAP_READERS +#include "Xlibint.h" +#include <X11/extensions/XKBproto.h> +#include "XKBlibint.h" +#include <X11/extensions/XI.h> + +/***====================================================================***/ + +extern void +#if NeedFunctionPrototypes +XkbNoteDeviceChanges( XkbDeviceChangesPtr old, + XkbExtensionDeviceNotifyEvent * new, + unsigned int wanted) +#else +XkbNoteDeviceChanges(old,new,wanted) + XkbDeviceChangesPtr old; + XkbExtensionDeviceNotifyEvent * new; + unsigned int wanted; +#endif +{ + if ((!old)||(!new)||(!wanted)||((new->reason&wanted)==0)) + return; + if ((wanted&new->reason)&XkbXI_ButtonActionsMask) { + if (old->changed&XkbXI_ButtonActionsMask) { + int first,last,newLast; + if (new->first_btn<old->first_btn) + first= new->first_btn; + else first= old->first_btn; + last= old->first_btn+old->num_btns-1; + newLast= new->first_btn+new->num_btns-1; + if (newLast>last) + last= newLast; + old->first_btn= first; + old->num_btns= (last-first)+1; + } + else { + old->changed|= XkbXI_ButtonActionsMask; + old->first_btn= new->first_btn; + old->num_btns= new->num_btns; + } + } + if ((wanted&new->reason)&XkbXI_IndicatorsMask) { + XkbDeviceLedChangesPtr this; + if (old->changed&XkbXI_IndicatorsMask) { + XkbDeviceLedChangesPtr found; + found= NULL; + for (this= &old->leds;this&&(!found);this=this->next) { + if ((this->led_class==new->led_class)&& + (this->led_id==new->led_id)) { + found= this; + } + } + if (!found) { + found= _XkbTypedCalloc(1,XkbDeviceLedChangesRec); + if (!found) + return; + found->next= old->leds.next; + found->led_class= new->led_class; + found->led_id= new->led_id; + old->leds.next= found; + } + if ((wanted&new->reason)&XkbXI_IndicatorNamesMask) + found->defined= new->leds_defined; + } + else { + old->changed|= ((wanted&new->reason)&XkbXI_IndicatorsMask); + old->leds.led_class= new->led_class; + old->leds.led_id= new->led_id; + old->leds.defined= new->leds_defined; + if (old->leds.next) { + XkbDeviceLedChangesPtr next; + for (this=old->leds.next;this;this=next) { + next= this->next; + _XkbFree(this); + } + old->leds.next= NULL; + } + } + } + return; +} + +/***====================================================================***/ + +static Status +#if NeedFunctionPrototypes +_XkbReadDeviceLedInfo( XkbReadBufferPtr buf, + unsigned present, + XkbDeviceInfoPtr devi) +#else +_XkbReadDeviceLedInfo(buf,present,devi) + XkbReadBufferPtr buf; + unsigned present; + XkbDeviceInfoPtr devi; +#endif +{ +register unsigned i,bit; +XkbDeviceLedInfoPtr devli; +xkbDeviceLedsWireDesc * wireli; + + wireli= _XkbGetTypedRdBufPtr(buf,1,xkbDeviceLedsWireDesc); + if (!wireli) + return BadLength; + devli= XkbAddDeviceLedInfo(devi,wireli->ledClass,wireli->ledID); + if (!devli) + return BadAlloc; + devli->phys_indicators= wireli->physIndicators; + + if (present&XkbXI_IndicatorStateMask) + devli->state= wireli->state; + + if (present&XkbXI_IndicatorNamesMask) { + devli->names_present= wireli->namesPresent; + if (devli->names_present) { + for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) { + if (wireli->namesPresent&bit) { + if (!_XkbCopyFromReadBuffer(buf,(char *)&devli->names[i],4)) + return BadLength; + } + } + } + } + + if (present&XkbXI_IndicatorMapsMask) { + devli->maps_present= wireli->mapsPresent; + if (devli->maps_present) { + XkbIndicatorMapPtr im; + xkbIndicatorMapWireDesc * wireim; + for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) { + if (wireli->mapsPresent&bit) { + wireim= _XkbGetTypedRdBufPtr(buf,1,xkbIndicatorMapWireDesc); + if (!wireim) + return BadAlloc; + im= &devli->maps[i]; + im->flags= wireim->flags; + im->which_groups= wireim->whichGroups; + im->groups= wireim->groups; + im->which_mods= wireim->whichMods; + im->mods.mask= wireim->mods; + im->mods.real_mods= wireim->realMods; + im->mods.vmods= wireim->virtualMods; + im->ctrls= wireim->ctrls; + } + } + } + } + return Success; +} + +static Status +#if NeedFunctionPrototypes +_XkbReadGetDeviceInfoReply( Display * dpy, + xkbGetDeviceInfoReply * rep, + XkbDeviceInfoPtr devi) +#else +_XkbReadGetDeviceInfoReply(dpy,rep,devi) + Display * dpy; + xkbGetDeviceInfoReply * rep; + XkbDeviceInfoPtr devi; +#endif +{ +XkbReadBufferRec buf; +XkbAction * act; +int tmp; + + if (!_XkbInitReadBuffer(dpy,&buf,(int)rep->length*4)) + return BadAlloc; + + if ((rep->totalBtns>0)&&(rep->totalBtns!=devi->num_btns)) { + tmp= XkbResizeDeviceButtonActions(devi,rep->totalBtns); + if (tmp!=Success) + return tmp; + } + if (rep->nBtnsWanted>0) { + act= &devi->btn_acts[rep->firstBtnWanted]; + bzero((char *)act,(rep->nBtnsWanted*sizeof(XkbAction))); + } + if (devi->name!=NULL) + _XkbFree(devi->name); + if (!_XkbGetReadBufferCountedString(&buf,&devi->name)) + goto BAILOUT; + if (rep->nBtnsRtrn>0) { + int size; + act= &devi->btn_acts[rep->firstBtnRtrn]; + size= rep->nBtnsRtrn*SIZEOF(xkbActionWireDesc); + if (!_XkbCopyFromReadBuffer(&buf,(char *)act,size)) + goto BAILOUT; + } + if (rep->nDeviceLedFBs>0) { + register int i; + for (i=0;i<rep->nDeviceLedFBs;i++) { + if ((tmp= _XkbReadDeviceLedInfo(&buf,rep->present,devi))!=Success) + return tmp; + } + } + tmp= _XkbFreeReadBuffer(&buf); + if (tmp) + fprintf(stderr,"GetDeviceInfo! Bad length (%d extra bytes)\n",tmp); + if (tmp || buf.error) + return BadLength; + return Success; +BAILOUT: + _XkbFreeReadBuffer(&buf); + return BadLength; +} + +XkbDeviceInfoPtr +#if NeedFunctionPrototypes +XkbGetDeviceInfo( Display * dpy, + unsigned which, + unsigned deviceSpec, + unsigned class, + unsigned id) +#else +XkbGetDeviceInfo(dpy,which,deviceSpec,class,id) + Display * dpy; + unsigned which; + unsigned deviceSpec; + unsigned class; + unsigned id; +#endif +{ + register xkbGetDeviceInfoReq * req; + xkbGetDeviceInfoReply rep; + Status status; + XkbDeviceInfoPtr devi; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) + return NULL; + LockDisplay(dpy); + GetReq(kbGetDeviceInfo, req); + req->reqType = dpy->xkb_info->codes->major_opcode; + req->xkbReqType = X_kbGetDeviceInfo; + req->deviceSpec = deviceSpec; + req->wanted= which; + req->allBtns= ((which&XkbXI_ButtonActionsMask)!=0); + req->firstBtn= req->nBtns= 0; + req->ledClass= class; + req->ledID= id; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return NULL; + } + devi= XkbAllocDeviceInfo(rep.deviceID,rep.totalBtns,rep.nDeviceLedFBs); + if (devi) { + devi->supported= rep.supported; + devi->unsupported= rep.unsupported; + devi->type= rep.devType; + devi->has_own_state= rep.hasOwnState; + devi->dflt_kbd_fb = rep.dfltKbdFB; + devi->dflt_led_fb = rep.dfltLedFB; + status= _XkbReadGetDeviceInfoReply(dpy,&rep,devi); + if (status!=Success) { + XkbFreeDeviceInfo(devi,XkbXI_AllDeviceFeaturesMask,True); + devi= NULL; + } + } + UnlockDisplay(dpy); + SyncHandle(); + return devi; +} + +Status +#if NeedFunctionPrototypes +XkbGetDeviceInfoChanges( Display * dpy, + XkbDeviceInfoPtr devi, + XkbDeviceChangesPtr changes) +#else +XkbGetDeviceInfoChanges(dpy,devi,changes) + Display * dpy; + XkbDeviceInfoPtr devi; + XkbDeviceChangesPtr changes; +#endif +{ + register xkbGetDeviceInfoReq * req; + xkbGetDeviceInfoReply rep; + Status status; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) + return BadMatch; + if ((changes->changed&XkbXI_AllDeviceFeaturesMask)==0) + return Success; + changes->changed&= ~XkbXI_AllDeviceFeaturesMask; + status= Success; + LockDisplay(dpy); + while ((changes->changed)&&(status==Success)) { + GetReq(kbGetDeviceInfo, req); + req->reqType = dpy->xkb_info->codes->major_opcode; + req->xkbReqType = X_kbGetDeviceInfo; + req->deviceSpec = devi->device_spec; + req->wanted= changes->changed; + req->allBtns= False; + if (changes->changed&XkbXI_ButtonActionsMask) { + req->firstBtn= changes->first_btn; + req->nBtns= changes->num_btns; + changes->changed&= ~XkbXI_ButtonActionsMask; + } + else req->firstBtn= req->nBtns= 0; + if (changes->changed&XkbXI_IndicatorsMask) { + req->ledClass= changes->leds.led_class; + req->ledID= changes->leds.led_id; + if (changes->leds.next==NULL) + changes->changed&= ~XkbXI_IndicatorsMask; + else { + XkbDeviceLedChangesPtr next; + next= changes->leds.next; + changes->leds= *next; + _XkbFree(next); + } + } + else { + req->ledClass= XkbDfltXIClass; + req->ledID= XkbDfltXIId; + } + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + status= BadLength; + break; + } + devi->supported|= rep.supported; + devi->unsupported|= rep.unsupported; + devi->type= rep.devType; + status= _XkbReadGetDeviceInfoReply(dpy,&rep,devi); + } + UnlockDisplay(dpy); + SyncHandle(); + return status; +} + +Status +#if NeedFunctionPrototypes +XkbGetDeviceButtonActions( Display * dpy, + XkbDeviceInfoPtr devi, + Bool all, + unsigned int first, + unsigned int num) +#else +XkbGetDeviceButtonActions(dpy,devi,all,first,num) + Display * dpy; + XkbDeviceInfoPtr devi; + Bool all; + unsigned int first; + unsigned int num; +#endif +{ + register xkbGetDeviceInfoReq * req; + xkbGetDeviceInfoReply rep; + Status status; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) + return BadMatch; + if (!devi) + return BadValue; + LockDisplay(dpy); + GetReq(kbGetDeviceInfo, req); + req->reqType = dpy->xkb_info->codes->major_opcode; + req->xkbReqType = X_kbGetDeviceInfo; + req->deviceSpec = devi->device_spec; + req->wanted= XkbXI_ButtonActionsMask; + req->allBtns= all; + req->firstBtn= first; + req->nBtns= num; + req->ledClass= XkbDfltXIClass; + req->ledID= XkbDfltXIId; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return BadLength; + } + devi->type= rep.devType; + devi->supported= rep.supported; + devi->unsupported= rep.unsupported; + status= _XkbReadGetDeviceInfoReply(dpy,&rep,devi); + UnlockDisplay(dpy); + SyncHandle(); + return status; +} + +Status +#if NeedFunctionPrototypes +XkbGetDeviceLedInfo( Display * dpy, + XkbDeviceInfoPtr devi, + unsigned int ledClass, + unsigned int ledId, + unsigned int which) +#else +XkbGetDeviceLedInfo(dpy,devi,ledClass,ledId,which) + Display * dpy; + XkbDeviceInfoPtr devi; + unsigned int ledClass; + unsigned int ledId; + unsigned int which; +#endif +{ + register xkbGetDeviceInfoReq * req; + xkbGetDeviceInfoReply rep; + Status status; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) + return BadMatch; + if (((which&XkbXI_IndicatorsMask)==0)||(which&(~XkbXI_IndicatorsMask))) + return BadMatch; + if (!devi) + return BadValue; + LockDisplay(dpy); + GetReq(kbGetDeviceInfo, req); + req->reqType = dpy->xkb_info->codes->major_opcode; + req->xkbReqType = X_kbGetDeviceInfo; + req->deviceSpec = devi->device_spec; + req->wanted= which; + req->allBtns= False; + req->firstBtn= req->nBtns= 0; + req->ledClass= ledClass; + req->ledID= ledId; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return BadLength; + } + devi->type= rep.devType; + devi->supported= rep.supported; + devi->unsupported= rep.unsupported; + status= _XkbReadGetDeviceInfoReply(dpy,&rep,devi); + UnlockDisplay(dpy); + SyncHandle(); + return status; +} + +/***====================================================================***/ + +typedef struct _LedInfoStuff { + Bool used; + XkbDeviceLedInfoPtr devli; +} LedInfoStuff; + +typedef struct _SetLedStuff { + unsigned wanted; + int num_info; + int dflt_class; + LedInfoStuff * dflt_kbd_fb; + LedInfoStuff * dflt_led_fb; + LedInfoStuff * info; +} SetLedStuff; + +static void +#if NeedFunctionPrototypes +_InitLedStuff(SetLedStuff *stuff,unsigned wanted,XkbDeviceInfoPtr devi) +#else +_InitLedStuff(stuff,wanted,devi) + SetLedStuff * stuff; + unsigned wanted; + XkbDeviceInfoPtr devi; +#endif +{ +int i; +register XkbDeviceLedInfoPtr devli; + + bzero(stuff,sizeof(SetLedStuff)); + stuff->wanted= wanted; + stuff->dflt_class= XkbXINone; + if ((devi->num_leds<1)||((wanted&XkbXI_IndicatorsMask)==0)) + return; + stuff->info= _XkbTypedCalloc(devi->num_leds,LedInfoStuff); + if (!stuff->info) + return; + stuff->num_info= devi->num_leds; + for (devli=&devi->leds[0],i=0;i<devi->num_leds;i++,devli++) { + stuff->info[i].devli= devli; + if (devli->led_class==KbdFeedbackClass) { + stuff->dflt_class= KbdFeedbackClass; + if (stuff->dflt_kbd_fb==NULL) + stuff->dflt_kbd_fb= &stuff->info[i]; + } + else if (devli->led_class==LedFeedbackClass) { + if (stuff->dflt_class==XkbXINone) + stuff->dflt_class= LedFeedbackClass; + if (stuff->dflt_led_fb==NULL) + stuff->dflt_led_fb= &stuff->info[i]; + } + } + return; +} + +static void +#if NeedFunctionPrototypes +_FreeLedStuff(SetLedStuff *stuff) +#else +_FreeLedStuff(stuff) + SetLedStuff *stuff; +#endif +{ + if ((stuff->num_info>0)&&(stuff->info!=NULL)) + _XkbFree(stuff->info); + bzero(stuff,sizeof(SetLedStuff)); + return; +} + +static int +#if NeedFunctionPrototypes +_XkbSizeLedInfo(unsigned changed,XkbDeviceLedInfoPtr devli) +#else +_XkbSizeLedInfo(changed,devli) + unsigned changed; + XkbDeviceLedInfoPtr devli; +#endif +{ +register int i,size; +register unsigned bit,namesNeeded,mapsNeeded; + + size= SIZEOF(xkbDeviceLedsWireDesc); + namesNeeded= mapsNeeded= 0; + if (changed&XkbXI_IndicatorNamesMask) + namesNeeded= devli->names_present; + if (changed&XkbXI_IndicatorMapsMask) + mapsNeeded= devli->maps_present; + if ((namesNeeded)||(mapsNeeded)) { + for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) { + if (namesNeeded&bit) + size+= 4; /* atoms are 4 bytes on the wire */ + if (mapsNeeded&bit) + size+= SIZEOF(xkbIndicatorMapWireDesc); + } + } + return size; +} + +static Bool +#if NeedFunctionPrototypes +_SizeMatches( SetLedStuff * stuff, + XkbDeviceLedChangesPtr changes, + int * sz_rtrn, + int * nleds_rtrn) +#else +_SizeMatches(stuff,changes,sz_rtrn,nleds_rtrn) + SetLedStuff * stuff; + XkbDeviceLedChangesPtr changes; + int * sz_rtrn; + int * nleds_rtrn; +#endif +{ +int i,nMatch,class,id; +LedInfoStuff * linfo; +Bool match; + + nMatch= 0; + class= changes->led_class; + id= changes->led_id; + if (class==XkbDfltXIClass) + class= stuff->dflt_class; + for (i=0,linfo=&stuff->info[0];i<stuff->num_info;i++,linfo++) { + XkbDeviceLedInfoPtr devli; + LedInfoStuff * dflt; + + devli= linfo->devli; + match= ((class==devli->led_class)||(class==XkbAllXIClasses)); + if (devli->led_class==KbdFeedbackClass) dflt= stuff->dflt_kbd_fb; + else dflt= stuff->dflt_led_fb; + match= match && (id==devli->led_id) || (id==XkbAllXIIds) || + ((id==XkbDfltXIId)&&(linfo==dflt)); + if (match) { + if (!linfo->used) { + *sz_rtrn+= _XkbSizeLedInfo(stuff->wanted,devli); + *nleds_rtrn+= 1; + linfo->used= True; + if ((class!=XkbAllXIClasses)&&(id!=XkbAllXIIds)) + return True; + } + nMatch++; + linfo->used= True; + } + } + return (nMatch>0); +} + +/***====================================================================***/ + + +static Status +#if NeedFunctionPrototypes +_XkbSetDeviceInfoSize( XkbDeviceInfoPtr devi, + XkbDeviceChangesPtr changes, + SetLedStuff * stuff, + int * sz_rtrn, + int * num_leds_rtrn) +#else +_XkbSetDeviceInfoSize(devi,changes,stuff,sz_rtrn,num_leds_rtrn) + XkbDeviceInfoPtr devi; + XkbDeviceChangesPtr changes; + SetLedStuff * stuff; + int * sz_rtrn; + int * num_leds_rtrn; +#endif +{ + *sz_rtrn= 0; + if ((changes->changed&XkbXI_ButtonActionsMask)&&(changes->num_btns>0)) { + if (!XkbXI_LegalDevBtn(devi,(changes->first_btn+changes->num_btns-1))) + return BadMatch; + *sz_rtrn+= changes->num_btns*SIZEOF(xkbActionWireDesc); + } + else { + changes->changed&= ~XkbXI_ButtonActionsMask; + changes->first_btn= changes->num_btns= 0; + } + if ((changes->changed&XkbXI_IndicatorsMask)&& + XkbLegalXILedClass(changes->leds.led_class)) { + XkbDeviceLedChangesPtr leds; + + for (leds=&changes->leds;leds!=NULL;leds= leds->next) { + if (!_SizeMatches(stuff,leds,sz_rtrn,num_leds_rtrn)) + return BadMatch; + } + } + else { + changes->changed&= ~XkbXI_IndicatorsMask; + *num_leds_rtrn= 0; + } + return Success; +} + +static char * +#if NeedFunctionPrototypes +_XkbWriteLedInfo(char *wire,unsigned changed,XkbDeviceLedInfoPtr devli) +#else +_XkbWriteLedInfo(wire,changed,devli) + char * wire; + unsigned changed; + XkbDeviceLedInfoPtr devli; +#endif +{ +register int i; +register unsigned bit,namesNeeded,mapsNeeded; +xkbDeviceLedsWireDesc * lwire; + + namesNeeded= mapsNeeded= 0; + if (changed&XkbXI_IndicatorNamesMask) + namesNeeded= devli->names_present; + if (changed&XkbXI_IndicatorMapsMask) + mapsNeeded= devli->maps_present; + + lwire= (xkbDeviceLedsWireDesc *)wire; + lwire->ledClass= devli->led_class; + lwire->ledID= devli->led_id; + lwire->namesPresent= namesNeeded; + lwire->mapsPresent= mapsNeeded; + lwire->physIndicators= devli->phys_indicators; + lwire->state= devli->state; + wire= (char *)&lwire[1]; + if (namesNeeded) { + CARD32 *awire; + awire= (CARD32 *)wire; + for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) { + if (namesNeeded&bit) { + *awire= (CARD32)devli->names[i]; + awire++; + } + } + wire= (char *)awire; + } + if (mapsNeeded) { + xkbIndicatorMapWireDesc *mwire; + + mwire= (xkbIndicatorMapWireDesc *)wire; + for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) { + if (mapsNeeded&bit) { + XkbIndicatorMapPtr map; + map= &devli->maps[i]; + mwire->flags= map->flags; + mwire->whichGroups= map->which_groups; + mwire->groups= map->groups; + mwire->whichMods= map->which_mods; + mwire->mods= map->mods.mask; + mwire->realMods= map->mods.real_mods; + mwire->virtualMods= map->mods.vmods; + mwire->ctrls= map->ctrls; + mwire++; + } + } + wire= (char *)mwire; + } + return wire; +} + + +static int +#if NeedFunctionPrototypes +_XkbWriteSetDeviceInfo( char * wire, + XkbDeviceChangesPtr changes, + SetLedStuff * stuff, + XkbDeviceInfoPtr devi) +#else +_XkbWriteSetDeviceInfo(wire,changes,stuff,devi) + char * wire; + XkbDeviceChangesPtr changes; + SetLedStuff * stuff; + XkbDeviceInfoPtr devi; +#endif +{ +char *start; + + start= wire; + if (changes->changed&XkbXI_ButtonActionsMask) { + int size; + size= changes->num_btns*SIZEOF(xkbActionWireDesc); + memcpy(wire,(char *)&devi->btn_acts[changes->first_btn],size); + wire+= size; + } + if (changes->changed&XkbXI_IndicatorsMask) { + register int i; + register LedInfoStuff *linfo; + + for (i=0,linfo=&stuff->info[0];i<stuff->num_info;i++,linfo++) { + if (linfo->used) { + register char *new_wire; + new_wire= _XkbWriteLedInfo(wire,stuff->wanted,linfo->devli); + if (!new_wire) + return wire-start; + wire= new_wire; + } + } + } + return wire-start; +} + +Bool +#if NeedFunctionPrototypes +XkbSetDeviceInfo( Display * dpy, + unsigned which, + XkbDeviceInfoPtr devi) +#else +XkbSetDeviceInfo(dpy,which,devi) + Display * dpy; + unsigned which; + XkbDeviceInfoPtr devi; +#endif +{ + register xkbSetDeviceInfoReq *req; + Status ok; + int size,nLeds; + XkbInfoPtr xkbi; + XkbDeviceChangesRec changes; + SetLedStuff lstuff; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) + return False; + if ((!devi) || (which&(~XkbXI_AllDeviceFeaturesMask)) || + ((which&XkbXI_ButtonActionsMask)&&(!XkbXI_DevHasBtnActs(devi)))|| + ((which&XkbXI_IndicatorsMask)&&(!XkbXI_DevHasLeds(devi)))) + return False; + + bzero((char *)&changes,sizeof(XkbDeviceChangesRec)); + changes.changed= which; + changes.first_btn= 0; + changes.num_btns= devi->num_btns; + changes.leds.led_class= XkbAllXIClasses; + changes.leds.led_id= XkbAllXIIds; + changes.leds.defined= 0; + size= nLeds= 0; + _InitLedStuff(&lstuff,changes.changed,devi); + if (_XkbSetDeviceInfoSize(devi,&changes,&lstuff,&size,&nLeds)!=Success) + return False; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbSetDeviceInfo, req); + req->length+= size/4; + req->reqType= xkbi->codes->major_opcode; + req->xkbReqType= X_kbSetDeviceInfo; + req->deviceSpec= devi->device_spec; + req->firstBtn= changes.first_btn; + req->nBtns= changes.num_btns; + req->change= changes.changed; + req->nDeviceLedFBs= nLeds; + if (size>0) { + char * wire; + BufAlloc(char *,wire,size); + ok= (wire!=NULL)&& + (_XkbWriteSetDeviceInfo(wire,&changes,&lstuff,devi)==size); + } + UnlockDisplay(dpy); + SyncHandle(); + _FreeLedStuff(&lstuff); + /* 12/11/95 (ef) -- XXX!! should clear changes here */ + return ok; +} + +Bool +#if NeedFunctionPrototypes +XkbChangeDeviceInfo( Display * dpy, + XkbDeviceInfoPtr devi, + XkbDeviceChangesPtr changes) +#else +XkbChangeDeviceInfo(dpy,devi,changes) + Display * dpy; + XkbDeviceInfoPtr devi; + XkbDeviceChangesPtr changes; +#endif +{ + register xkbSetDeviceInfoReq *req; + Status ok; + int size,nLeds; + XkbInfoPtr xkbi; + SetLedStuff lstuff; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) + return False; + if ((!devi) || (changes->changed&(~XkbXI_AllDeviceFeaturesMask)) || + ((changes->changed&XkbXI_ButtonActionsMask)&& + (!XkbXI_DevHasBtnActs(devi)))|| + ((changes->changed&XkbXI_IndicatorsMask)&&(!XkbXI_DevHasLeds(devi)))) + return False; + + size= nLeds= 0; + _InitLedStuff(&lstuff,changes->changed,devi); + if (_XkbSetDeviceInfoSize(devi,changes,&lstuff,&size,&nLeds)!=Success) + return False; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbSetDeviceInfo, req); + req->length+= size/4; + req->reqType= xkbi->codes->major_opcode; + req->xkbReqType= X_kbSetDeviceInfo; + req->deviceSpec= devi->device_spec; + req->firstBtn= changes->first_btn; + req->nBtns= changes->num_btns; + req->change= changes->changed; + req->nDeviceLedFBs= nLeds; + if (size>0) { + char * wire; + BufAlloc(char *,wire,size); + ok= (wire!=NULL)&& + (_XkbWriteSetDeviceInfo(wire,changes,&lstuff,devi)==size); + } + UnlockDisplay(dpy); + SyncHandle(); + _FreeLedStuff(&lstuff); + /* 12/11/95 (ef) -- XXX!! should clear changes here */ + return ok; +} + +Bool +#if NeedFunctionPrototypes +XkbSetDeviceLedInfo( Display * dpy, + XkbDeviceInfoPtr devi, + unsigned ledClass, + unsigned ledID, + unsigned which) +#else +XkbSetDeviceLedInfo(dpy,devi,ledClass,ledID,which) + Display * dpy; + XkbDeviceInfoPtr devi; + unsigned ledClass; + unsigned ledID; + unsigned which; +#endif +{ + return False; +} + +Bool +#if NeedFunctionPrototypes +XkbSetDeviceButtonActions( Display * dpy, + XkbDeviceInfoPtr devi, + unsigned int first, + unsigned int nBtns) +#else +XkbSetDeviceButtonActions(dpy,devi,first,nBtns) + Display * dpy; + XkbDeviceInfoPtr devi; + unsigned int first; + unsigned int nBtns; +#endif +{ + register xkbSetDeviceInfoReq *req; + Status ok; + int size,nLeds; + XkbInfoPtr xkbi; + XkbDeviceChangesRec changes; + SetLedStuff lstuff; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) + return False; + if ((!devi)||(!XkbXI_DevHasBtnActs(devi))||(first+nBtns>devi->num_btns)) + return False; + if (nBtns==0) + return True; + + bzero((char *)&changes,sizeof(XkbDeviceChangesRec)); + changes.changed= XkbXI_ButtonActionsMask; + changes.first_btn= first; + changes.num_btns= nBtns; + changes.leds.led_class= XkbXINone; + changes.leds.led_id= XkbXINone; + changes.leds.defined= 0; + size= nLeds= 0; + if (_XkbSetDeviceInfoSize(devi,&changes,NULL,&size,&nLeds)!=Success) + return False; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbSetDeviceInfo, req); + req->length+= size/4; + req->reqType= xkbi->codes->major_opcode; + req->xkbReqType= X_kbSetDeviceInfo; + req->deviceSpec= devi->device_spec; + req->firstBtn= changes.first_btn; + req->nBtns= changes.num_btns; + req->change= changes.changed; + req->nDeviceLedFBs= nLeds; + if (size>0) { + char * wire; + BufAlloc(char *,wire,size); + ok= (wire!=NULL)&& + (_XkbWriteSetDeviceInfo(wire,&changes,&lstuff,devi)==size); + } + UnlockDisplay(dpy); + SyncHandle(); + return ok; +} diff --git a/src/xkb/XKBGAlloc.c b/src/xkb/XKBGAlloc.c new file mode 100644 index 00000000..c89e1197 --- /dev/null +++ b/src/xkb/XKBGAlloc.c @@ -0,0 +1,1377 @@ +/* $Xorg: XKBGAlloc.c,v 1.3 2000/08/17 19:45:01 cpqbld Exp $ */ +/************************************************************ +Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc. + +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 Silicon Graphics not be +used in advertising or publicity pertaining to distribution +of the software without specific prior written permission. +Silicon Graphics makes no representation about the suitability +of this software for any purpose. It is provided "as is" +without any express or implied warranty. + +SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS +SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON +GRAPHICS 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. + +********************************************************/ + +#define NEED_EVENTS +#define NEED_REPLIES + +#ifndef XKB_IN_SERVER + +#include <stdio.h> +#include "Xlibint.h" +#include "XKBlibint.h" +#include <X11/extensions/XKBgeom.h> +#include <X11/extensions/XKBproto.h> + +#else + +#include <stdio.h> +#include "X.h" +#include "Xproto.h" +#include "misc.h" +#include "inputstr.h" +#include "XKBsrv.h" +#include "XKBgeom.h" + +#endif /* XKB_IN_SERVER */ + +#ifdef X_NOT_POSIX +#define Size_t unsigned int +#else +#define Size_t size_t +#endif + +/***====================================================================***/ + +static void +#if NeedFunctionPrototypes +_XkbFreeGeomLeafElems( Bool freeAll, + int first, + int count, + unsigned short * num_inout, + unsigned short * sz_inout, + char ** elems, + unsigned int elem_sz) +#else +_XkbFreeGeomLeafElems(freeAll,first,count,num_inout,sz_inout,elems,elem_sz) + Bool freeAll; + int first; + int count; + unsigned short * num_inout; + unsigned short * sz_inout; + char ** elems; + unsigned int elem_sz; +#endif +{ + if ((freeAll)||(*elems==NULL)) { + *num_inout= *sz_inout= 0; + if (*elems!=NULL) { + _XkbFree(*elems); + *elems= NULL; + } + return; + } + + if ((first>=(*num_inout))||(first<0)||(count<1)) + return; + + if (first+count>=(*num_inout)) { + /* truncating the array is easy */ + (*num_inout)= first; + } + else { + char * ptr; + int extra; + ptr= *elems; + extra= ((*num_inout)-(first+count))*elem_sz; + if (extra>0) + memmove(&ptr[first*elem_sz],&ptr[(first+count)*elem_sz],extra); + (*num_inout)-= count; + } + return; +} + +typedef void (*ContentsClearFunc)( +#if NeedFunctionPrototypes + char * /* priv */ +#endif +); + +static void +#if NeedFunctionPrototypes +_XkbFreeGeomNonLeafElems( Bool freeAll, + int first, + int count, + unsigned short * num_inout, + unsigned short * sz_inout, + char ** elems, + unsigned int elem_sz, + ContentsClearFunc freeFunc) +#else +_XkbFreeGeomNonLeafElems(freeAll,first,count,num_inout,sz_inout,elems,elem_sz, + freeFunc) + Bool freeAll; + int first; + int count; + unsigned short * num_inout; + unsigned short * sz_inout; + char ** elems; + unsigned int elem_sz; + ContentsClearFunc freeFunc; +#endif +{ +register int i; +register char *ptr; + + if (freeAll) { + first= 0; + count= (*num_inout); + } + else if ((first>=(*num_inout))||(first<0)||(count<1)) + return; + else if (first+count>(*num_inout)) + count= (*num_inout)-first; + if (*elems==NULL) + return; + + if (freeFunc) { + ptr= *elems; + ptr+= first*elem_sz; + for (i=0;i<count;i++) { + (*freeFunc)(ptr); + ptr+= elem_sz; + } + } + if (freeAll) { + (*num_inout)= (*sz_inout)= 0; + if (*elems) { + _XkbFree(*elems); + *elems= NULL; + } + } + else if (first+count>=(*num_inout)) + *num_inout= first; + else { + i= ((*num_inout)-(first+count))*elem_sz; + ptr= *elems; + memmove(&ptr[first*elem_sz],&ptr[(first+count)*elem_sz],i); + (*num_inout)-= count; + } + return; +} + +/***====================================================================***/ + +static void +#if NeedFunctionPrototypes +_XkbClearProperty(char *prop_in) +#else +_XkbClearProperty(prop_in) + char * prop_in; +#endif +{ +XkbPropertyPtr prop= (XkbPropertyPtr)prop_in; + + if (prop->name) { + _XkbFree(prop->name); + prop->name= NULL; + } + if (prop->value) { + _XkbFree(prop->value); + prop->value= NULL; + } + return; +} + +void +#if NeedFunctionPrototypes +XkbFreeGeomProperties( XkbGeometryPtr geom, + int first, + int count, + Bool freeAll) +#else +XkbFreeGeomProperties(geom,first,count,freeAll) + XkbGeometryPtr geom; + int first; + int count; + Bool freeAll; +#endif +{ + _XkbFreeGeomNonLeafElems(freeAll,first,count, + &geom->num_properties,&geom->sz_properties, + (char **)&geom->properties, + sizeof(XkbPropertyRec),_XkbClearProperty); + return; +} + +/***====================================================================***/ + +void +#if NeedFunctionPrototypes +XkbFreeGeomKeyAliases( XkbGeometryPtr geom, + int first, + int count, + Bool freeAll) +#else +XkbFreeGeomKeyAliases(geom,first,count,freeAll) + XkbGeometryPtr geom; + int first; + int count; + Bool freeAll; +#endif +{ + _XkbFreeGeomLeafElems(freeAll,first,count, + &geom->num_key_aliases,&geom->sz_key_aliases, + (char **)&geom->key_aliases, + sizeof(XkbKeyAliasRec)); + return; +} + +/***====================================================================***/ + +static void +#if NeedFunctionPrototypes +_XkbClearColor(char *color_in) +#else +_XkbClearColor(color_in) + char * color_in; +#endif +{ +XkbColorPtr color= (XkbColorPtr)color_in; + + if (color->spec) + _XkbFree(color->spec); + return; +} + +void +#if NeedFunctionPrototypes +XkbFreeGeomColors(XkbGeometryPtr geom,int first,int count,Bool freeAll) +#else +XkbFreeGeomColors(geom,first,count,freeAll) + XkbGeometryPtr geom; + int first; + int count; + Bool freeAll; +#endif +{ + _XkbFreeGeomNonLeafElems(freeAll,first,count, + &geom->num_colors,&geom->sz_colors, + (char **)&geom->colors, + sizeof(XkbColorRec),_XkbClearColor); + return; +} + +/***====================================================================***/ + +void +#if NeedFunctionPrototypes +XkbFreeGeomPoints(XkbOutlinePtr outline,int first,int count,Bool freeAll) +#else +XkbFreeGeomPoints(outline,first,count,freeAll) + XkbOutlinePtr outline; + int first; + int count; + Bool freeAll; +#endif +{ + _XkbFreeGeomLeafElems(freeAll,first,count, + &outline->num_points,&outline->sz_points, + (char **)&outline->points, + sizeof(XkbPointRec)); + return; +} + +/***====================================================================***/ + +static void +#if NeedFunctionPrototypes +_XkbClearOutline(char *outline_in) +#else +_XkbClearOutline(outline_in) + char * outline_in; +#endif +{ +XkbOutlinePtr outline= (XkbOutlinePtr)outline_in; + + if (outline->points!=NULL) + XkbFreeGeomPoints(outline,0,outline->num_points,True); + return; +} + +void +#if NeedFunctionPrototypes +XkbFreeGeomOutlines(XkbShapePtr shape,int first,int count,Bool freeAll) +#else +XkbFreeGeomOutlines(shape,first,count,freeAll) + XkbShapePtr shape; + int first; + int count; + Bool freeAll; +#endif +{ + _XkbFreeGeomNonLeafElems(freeAll,first,count, + &shape->num_outlines,&shape->sz_outlines, + (char **)&shape->outlines, + sizeof(XkbOutlineRec),_XkbClearOutline); + + return; +} + +/***====================================================================***/ + +static void +#if NeedFunctionPrototypes +_XkbClearShape(char *shape_in) +#else +_XkbClearShape(shape_in) + char * shape_in; +#endif +{ +XkbShapePtr shape= (XkbShapePtr)shape_in; + + if (shape->outlines) + XkbFreeGeomOutlines(shape,0,shape->num_outlines,True); + return; +} + +void +#if NeedFunctionPrototypes +XkbFreeGeomShapes(XkbGeometryPtr geom,int first,int count,Bool freeAll) +#else +XkbFreeGeomShapes(geom,first,count,freeAll) + XkbGeometryPtr geom; + int first; + int count; + Bool freeAll; +#endif +{ + _XkbFreeGeomNonLeafElems(freeAll,first,count, + &geom->num_shapes,&geom->sz_shapes, + (char **)&geom->shapes, + sizeof(XkbShapeRec),_XkbClearShape); + return; +} + +/***====================================================================***/ + +void +#if NeedFunctionPrototypes +XkbFreeGeomOverlayKeys(XkbOverlayRowPtr row,int first,int count,Bool freeAll) +#else +XkbFreeGeomOverlayKeys(row,first,count,freeAll) + XkbOverlayRowPtr row; + int first; + int count; + Bool freeAll; +#endif +{ + _XkbFreeGeomLeafElems(freeAll,first,count, + &row->num_keys,&row->sz_keys, + (char **)&row->keys, + sizeof(XkbOverlayKeyRec)); + return; +} + +/***====================================================================***/ + +static void +#if NeedFunctionPrototypes +_XkbClearOverlayRow(char *row_in) +#else +_XkbClearOverlayRow(row_in) + char * row_in; +#endif +{ +XkbOverlayRowPtr row= (XkbOverlayRowPtr)row_in; + + if (row->keys!=NULL) + XkbFreeGeomOverlayKeys(row,0,row->num_keys,True); + return; +} + +void +#if NeedFunctionPrototypes +XkbFreeGeomOverlayRows(XkbOverlayPtr overlay,int first,int count,Bool freeAll) +#else +XkbFreeGeomOverlayRows(overlay,first,count,freeAll) + XkbOverlayPtr overlay; + int first; + int count; + Bool freeAll; +#endif +{ + _XkbFreeGeomNonLeafElems(freeAll,first,count, + &overlay->num_rows,&overlay->sz_rows, + (char **)&overlay->rows, + sizeof(XkbOverlayRowRec),_XkbClearOverlayRow); + return; +} + +/***====================================================================***/ + +static void +#if NeedFunctionPrototypes +_XkbClearOverlay(char *overlay_in) +#else +_XkbClearOverlay(overlay_in) + char * overlay_in; +#endif +{ +XkbOverlayPtr overlay= (XkbOverlayPtr)overlay_in; + + if (overlay->rows!=NULL) + XkbFreeGeomOverlayRows(overlay,0,overlay->num_rows,True); + return; +} + +void +#if NeedFunctionPrototypes +XkbFreeGeomOverlays(XkbSectionPtr section,int first,int count,Bool freeAll) +#else +XkbFreeGeomOverlays(section,first,count,freeAll) + XkbSectionPtr section; + int first; + int count; + Bool freeAll; +#endif +{ + _XkbFreeGeomNonLeafElems(freeAll,first,count, + §ion->num_overlays,§ion->sz_overlays, + (char **)§ion->overlays, + sizeof(XkbOverlayRec),_XkbClearOverlay); + return; +} + +/***====================================================================***/ + +void +#if NeedFunctionPrototypes +XkbFreeGeomKeys(XkbRowPtr row,int first,int count,Bool freeAll) +#else +XkbFreeGeomKeys(row,first,count,freeAll) + XkbRowPtr row; + int first; + int count; + Bool freeAll; +#endif +{ + _XkbFreeGeomLeafElems(freeAll,first,count, + &row->num_keys,&row->sz_keys, + (char **)&row->keys, + sizeof(XkbKeyRec)); + return; +} + +/***====================================================================***/ + +static void +#if NeedFunctionPrototypes +_XkbClearRow(char *row_in) +#else +_XkbClearRow(row_in) + char * row_in; +#endif +{ +XkbRowPtr row= (XkbRowPtr)row_in; + + if (row->keys!=NULL) + XkbFreeGeomKeys(row,0,row->num_keys,True); + return; +} + +void +#if NeedFunctionPrototypes +XkbFreeGeomRows(XkbSectionPtr section,int first,int count,Bool freeAll) +#else +XkbFreeGeomRows(section,first,count,freeAll) + XkbSectionPtr section; + int first; + int count; + Bool freeAll; +#endif +{ + _XkbFreeGeomNonLeafElems(freeAll,first,count, + §ion->num_rows,§ion->sz_rows, + (char **)§ion->rows, + sizeof(XkbRowRec),_XkbClearRow); +} + +/***====================================================================***/ + +static void +#if NeedFunctionPrototypes +_XkbClearSection(char *section_in) +#else +_XkbClearSection(section_in) + char * section_in; +#endif +{ +XkbSectionPtr section= (XkbSectionPtr)section_in; + + if (section->rows!=NULL) + XkbFreeGeomRows(section,0,section->num_rows,True); + if (section->doodads!=NULL) { + XkbFreeGeomDoodads(section->doodads,section->num_doodads,True); + section->doodads= NULL; + } + return; +} + +void +#if NeedFunctionPrototypes +XkbFreeGeomSections(XkbGeometryPtr geom,int first,int count,Bool freeAll) +#else +XkbFreeGeomSections(geom,first,count,freeAll) + XkbGeometryPtr geom; + int first; + int count; + Bool freeAll; +#endif +{ + _XkbFreeGeomNonLeafElems(freeAll,first,count, + &geom->num_sections,&geom->sz_sections, + (char **)&geom->sections, + sizeof(XkbSectionRec),_XkbClearSection); + return; +} + +/***====================================================================***/ + +static void +#if NeedFunctionPrototypes +_XkbClearDoodad(char *doodad_in) +#else +_XkbClearDoodad(doodad_in) + char * doodad_in; +#endif +{ +XkbDoodadPtr doodad= (XkbDoodadPtr)doodad_in; + + switch (doodad->any.type) { + case XkbTextDoodad: + { + if (doodad->text.text!=NULL) { + _XkbFree(doodad->text.text); + doodad->text.text= NULL; + } + if (doodad->text.font!=NULL) { + _XkbFree(doodad->text.font); + doodad->text.font= NULL; + } + } + break; + case XkbLogoDoodad: + { + if (doodad->logo.logo_name!=NULL) { + _XkbFree(doodad->logo.logo_name); + doodad->logo.logo_name= NULL; + } + } + break; + } + return; +} + +void +#if NeedFunctionPrototypes +XkbFreeGeomDoodads(XkbDoodadPtr doodads,int nDoodads,Bool freeAll) +#else +XkbFreeGeomDoodads(doodads,nDoodads,freeAll) + XkbDoodadPtr doodads; + int nDoodads; + Bool freeAll; +#endif +{ +register int i; +register XkbDoodadPtr doodad; + + if (doodads) { + for (i=0,doodad= doodads;i<nDoodads;i++,doodad++) { + _XkbClearDoodad((char *)doodad); + } + if (freeAll) + _XkbFree(doodads); + } + return; +} + +void +#if NeedFunctionPrototypes +XkbFreeGeometry(XkbGeometryPtr geom,unsigned which,Bool freeMap) +#else +XkbFreeGeometry(geom,which,freeMap) + XkbGeometryPtr geom; + unsigned which; + Bool freeMap; +#endif +{ + if (geom==NULL) + return; + if (freeMap) + which= XkbGeomAllMask; + if ((which&XkbGeomPropertiesMask)&&(geom->properties!=NULL)) + XkbFreeGeomProperties(geom,0,geom->num_properties,True); + if ((which&XkbGeomColorsMask)&&(geom->colors!=NULL)) + XkbFreeGeomColors(geom,0,geom->num_colors,True); + if ((which&XkbGeomShapesMask)&&(geom->shapes!=NULL)) + XkbFreeGeomShapes(geom,0,geom->num_shapes,True); + if ((which&XkbGeomSectionsMask)&&(geom->sections!=NULL)) + XkbFreeGeomSections(geom,0,geom->num_sections,True); + if ((which&XkbGeomDoodadsMask)&&(geom->doodads!= NULL)) { + XkbFreeGeomDoodads(geom->doodads,geom->num_doodads,True); + geom->doodads= NULL; + geom->num_doodads= geom->sz_doodads= 0; + } + if ((which&XkbGeomKeyAliasesMask)&&(geom->key_aliases!=NULL)) + XkbFreeGeomKeyAliases(geom,0,geom->num_key_aliases,True); + if (freeMap) { + if (geom->label_font!=NULL) { + _XkbFree(geom->label_font); + geom->label_font= NULL; + } + _XkbFree(geom); + } + return; +} + +/***====================================================================***/ + +static Status +#if NeedFunctionPrototypes +_XkbGeomAlloc( XPointer * old, + unsigned short * num, + unsigned short * total, + int num_new, + Size_t sz_elem) +#else +_XkbGeomAlloc(old,num,total,num_new,sz_elem) + XPointer * old; + unsigned short * num; + unsigned short * total; + int num_new; + Size_t sz_elem; +#endif +{ + if (num_new<1) + return Success; + if ((*old)==NULL) + *num= *total= 0; + + if ((*num)+num_new<=(*total)) + return Success; + + *total= (*num)+num_new; + if ((*old)!=NULL) + (*old)= (XPointer)_XkbRealloc((*old),(*total)*sz_elem); + else (*old)= (XPointer)_XkbCalloc((*total),sz_elem); + if ((*old)==NULL) { + *total= *num= 0; + return BadAlloc; + } + + if (*num>0) { + char *tmp= (char *)(*old); + bzero(&tmp[sz_elem*(*num)],(num_new*sz_elem)); + } + return Success; +} + +#define _XkbAllocProps(g,n) _XkbGeomAlloc((XPointer *)&(g)->properties,\ + &(g)->num_properties,&(g)->sz_properties,\ + (n),sizeof(XkbPropertyRec)) +#define _XkbAllocColors(g,n) _XkbGeomAlloc((XPointer *)&(g)->colors,\ + &(g)->num_colors,&(g)->sz_colors,\ + (n),sizeof(XkbColorRec)) +#define _XkbAllocShapes(g,n) _XkbGeomAlloc((XPointer *)&(g)->shapes,\ + &(g)->num_shapes,&(g)->sz_shapes,\ + (n),sizeof(XkbShapeRec)) +#define _XkbAllocSections(g,n) _XkbGeomAlloc((XPointer *)&(g)->sections,\ + &(g)->num_sections,&(g)->sz_sections,\ + (n),sizeof(XkbSectionRec)) +#define _XkbAllocDoodads(g,n) _XkbGeomAlloc((XPointer *)&(g)->doodads,\ + &(g)->num_doodads,&(g)->sz_doodads,\ + (n),sizeof(XkbDoodadRec)) +#define _XkbAllocKeyAliases(g,n) _XkbGeomAlloc((XPointer *)&(g)->key_aliases,\ + &(g)->num_key_aliases,&(g)->sz_key_aliases,\ + (n),sizeof(XkbKeyAliasRec)) + +#define _XkbAllocOutlines(s,n) _XkbGeomAlloc((XPointer *)&(s)->outlines,\ + &(s)->num_outlines,&(s)->sz_outlines,\ + (n),sizeof(XkbOutlineRec)) +#define _XkbAllocRows(s,n) _XkbGeomAlloc((XPointer *)&(s)->rows,\ + &(s)->num_rows,&(s)->sz_rows,\ + (n),sizeof(XkbRowRec)) +#define _XkbAllocPoints(o,n) _XkbGeomAlloc((XPointer *)&(o)->points,\ + &(o)->num_points,&(o)->sz_points,\ + (n),sizeof(XkbPointRec)) +#define _XkbAllocKeys(r,n) _XkbGeomAlloc((XPointer *)&(r)->keys,\ + &(r)->num_keys,&(r)->sz_keys,\ + (n),sizeof(XkbKeyRec)) +#define _XkbAllocOverlays(s,n) _XkbGeomAlloc((XPointer *)&(s)->overlays,\ + &(s)->num_overlays,&(s)->sz_overlays,\ + (n),sizeof(XkbOverlayRec)) +#define _XkbAllocOverlayRows(o,n) _XkbGeomAlloc((XPointer *)&(o)->rows,\ + &(o)->num_rows,&(o)->sz_rows,\ + (n),sizeof(XkbOverlayRowRec)) +#define _XkbAllocOverlayKeys(r,n) _XkbGeomAlloc((XPointer *)&(r)->keys,\ + &(r)->num_keys,&(r)->sz_keys,\ + (n),sizeof(XkbOverlayKeyRec)) + +Status +#if NeedFunctionPrototypes +XkbAllocGeomProps(XkbGeometryPtr geom,int nProps) +#else +XkbAllocGeomProps(geom,nProps) + XkbGeometryPtr geom; + int nProps; +#endif +{ + return _XkbAllocProps(geom,nProps); +} + +Status +#if NeedFunctionPrototypes +XkbAllocGeomColors(XkbGeometryPtr geom,int nColors) +#else +XkbAllocGeomColors(geom,nColors) + XkbGeometryPtr geom; + int nColors; +#endif +{ + return _XkbAllocColors(geom,nColors); +} + +Status +#if NeedFunctionPrototypes +XkbAllocGeomKeyAliases(XkbGeometryPtr geom,int nKeyAliases) +#else +XkbAllocGeomKeyAliases(geom,nKeyAliases) + XkbGeometryPtr geom; + int nKeyAliases; +#endif +{ + return _XkbAllocKeyAliases(geom,nKeyAliases); +} + +Status +#if NeedFunctionPrototypes +XkbAllocGeomShapes(XkbGeometryPtr geom,int nShapes) +#else +XkbAllocGeomShapes(geom,nShapes) + XkbGeometryPtr geom; + int nShapes; +#endif +{ + return _XkbAllocShapes(geom,nShapes); +} + +Status +#if NeedFunctionPrototypes +XkbAllocGeomSections(XkbGeometryPtr geom,int nSections) +#else +XkbAllocGeomSections(geom,nSections) + XkbGeometryPtr geom; + int nSections; +#endif +{ + return _XkbAllocSections(geom,nSections); +} + +Status +#if NeedFunctionPrototypes +XkbAllocGeomOverlays(XkbSectionPtr section,int nOverlays) +#else +XkbAllocGeomOverlays(section,nOverlays) + XkbSectionPtr section; + int nOverlays; +#endif +{ + return _XkbAllocOverlays(section,nOverlays); +} + +Status +#if NeedFunctionPrototypes +XkbAllocGeomOverlayRows(XkbOverlayPtr overlay,int nRows) +#else +XkbAllocGeomOverlayRows(overlay,nRows) + XkbOverlayPtr overlay; + int nRows; +#endif +{ + return _XkbAllocOverlayRows(overlay,nRows); +} + +Status +#if NeedFunctionPrototypes +XkbAllocGeomOverlayKeys(XkbOverlayRowPtr row,int nKeys) +#else +XkbAllocGeomOverlayKeys(row,nKeys) + XkbOverlayRowPtr row; + int nKeys; +#endif +{ + return _XkbAllocOverlayKeys(row,nKeys); +} + +Status +#if NeedFunctionPrototypes +XkbAllocGeomDoodads(XkbGeometryPtr geom,int nDoodads) +#else +XkbAllocGeomDoodads(geom,nDoodads) + XkbGeometryPtr geom; + int nDoodads; +#endif +{ + return _XkbAllocDoodads(geom,nDoodads); +} + +Status +#if NeedFunctionPrototypes +XkbAllocGeomSectionDoodads(XkbSectionPtr section,int nDoodads) +#else +XkbAllocGeomSectionDoodads(section,nDoodads) + XkbSectionPtr section; + int nDoodads; +#endif +{ + return _XkbAllocDoodads(section,nDoodads); +} + +Status +#if NeedFunctionPrototypes +XkbAllocGeomOutlines(XkbShapePtr shape,int nOL) +#else +XkbAllocGeomOutlines(shape,nOL) + XkbShapePtr shape; + int nOL; +#endif +{ + return _XkbAllocOutlines(shape,nOL); +} + +Status +#if NeedFunctionPrototypes +XkbAllocGeomRows(XkbSectionPtr section,int nRows) +#else +XkbAllocGeomRows(section,nRows) + XkbSectionPtr section; + int nRows; +#endif +{ + return _XkbAllocRows(section,nRows); +} + +Status +#if NeedFunctionPrototypes +XkbAllocGeomPoints(XkbOutlinePtr ol,int nPts) +#else +XkbAllocGeomPoints(ol,nPts) + XkbOutlinePtr ol; + int nPts; +#endif +{ + return _XkbAllocPoints(ol,nPts); +} + +Status +#if NeedFunctionPrototypes +XkbAllocGeomKeys(XkbRowPtr row,int nKeys) +#else +XkbAllocGeomKeys(row,nKeys) + XkbRowPtr row; + int nKeys; +#endif +{ + return _XkbAllocKeys(row,nKeys); +} + +Status +#if NeedFunctionPrototypes +XkbAllocGeometry(XkbDescPtr xkb,XkbGeometrySizesPtr sizes) +#else +XkbAllocGeometry(xkb,sizes) + XkbDescPtr xkb; + XkbGeometrySizesPtr sizes; +#endif +{ +XkbGeometryPtr geom; +Status rtrn; + + if (xkb->geom==NULL) { + xkb->geom= _XkbTypedCalloc(1,XkbGeometryRec); + if (!xkb->geom) + return BadAlloc; + } + geom= xkb->geom; + if ((sizes->which&XkbGeomPropertiesMask)&& + ((rtrn=_XkbAllocProps(geom,sizes->num_properties))!=Success)) { + goto BAIL; + } + if ((sizes->which&XkbGeomColorsMask)&& + ((rtrn=_XkbAllocColors(geom,sizes->num_colors))!=Success)) { + goto BAIL; + } + if ((sizes->which&XkbGeomShapesMask)&& + ((rtrn=_XkbAllocShapes(geom,sizes->num_shapes))!=Success)) { + goto BAIL; + } + if ((sizes->which&XkbGeomSectionsMask)&& + ((rtrn=_XkbAllocSections(geom,sizes->num_sections))!=Success)) { + goto BAIL; + } + if ((sizes->which&XkbGeomDoodadsMask)&& + ((rtrn=_XkbAllocDoodads(geom,sizes->num_doodads))!=Success)) { + goto BAIL; + } + if ((sizes->which&XkbGeomKeyAliasesMask)&& + ((rtrn=_XkbAllocKeyAliases(geom,sizes->num_key_aliases))!=Success)) { + goto BAIL; + } + return Success; +BAIL: + XkbFreeGeometry(geom,XkbGeomAllMask,True); + xkb->geom= NULL; + return rtrn; +} + +/***====================================================================***/ + +XkbPropertyPtr +#if NeedFunctionPrototypes +XkbAddGeomProperty(XkbGeometryPtr geom,char *name,char *value) +#else +XkbAddGeomProperty(geom,name,value) + XkbGeometryPtr geom; + char * name; + char * value; +#endif +{ +register int i; +register XkbPropertyPtr prop; + + if ((!geom)||(!name)||(!value)) + return NULL; + for (i=0,prop=geom->properties;i<geom->num_properties;i++,prop++) { + if ((prop->name)&&(strcmp(name,prop->name)==0)) { + if (prop->value) + _XkbFree(prop->value); + prop->value= (char *)_XkbAlloc(strlen(value)+1); + if (prop->value) + strcpy(prop->value,value); + return prop; + } + } + if ((geom->num_properties>=geom->sz_properties)&& + (_XkbAllocProps(geom,1)!=Success)) { + return NULL; + } + prop= &geom->properties[geom->num_properties]; + prop->name= (char *)_XkbAlloc(strlen(name)+1); + if (!name) + return NULL; + strcpy(prop->name,name); + prop->value= (char *)_XkbAlloc(strlen(value)+1); + if (!value) { + _XkbFree(prop->name); + prop->name= NULL; + return NULL; + } + strcpy(prop->value,value); + geom->num_properties++; + return prop; +} + +XkbKeyAliasPtr +#if NeedFunctionPrototypes +XkbAddGeomKeyAlias(XkbGeometryPtr geom,char *aliasStr,char *realStr) +#else +XkbAddGeomKeyAlias(geom,aliasStr,realStr) + XkbGeometryPtr geom; + char * aliasStr; + char * realStr; +#endif +{ +register int i; +register XkbKeyAliasPtr alias; + + if ((!geom)||(!aliasStr)||(!realStr)||(!aliasStr[0])||(!realStr[0])) + return NULL; + for (i=0,alias=geom->key_aliases;i<geom->num_key_aliases;i++,alias++) { + if (strncmp(alias->alias,aliasStr,XkbKeyNameLength)==0) { + bzero(alias->real,XkbKeyNameLength); + strncpy(alias->real,realStr,XkbKeyNameLength); + return alias; + } + } + if ((geom->num_key_aliases>=geom->sz_key_aliases)&& + (_XkbAllocKeyAliases(geom,1)!=Success)) { + return NULL; + } + alias= &geom->key_aliases[geom->num_key_aliases]; + bzero(alias,sizeof(XkbKeyAliasRec)); + strncpy(alias->alias,aliasStr,XkbKeyNameLength); + strncpy(alias->real,realStr,XkbKeyNameLength); + geom->num_key_aliases++; + return alias; +} + +XkbColorPtr +#if NeedFunctionPrototypes +XkbAddGeomColor(XkbGeometryPtr geom,char *spec,unsigned int pixel) +#else +XkbAddGeomColor(geom,spec,pixel) + XkbGeometryPtr geom; + char * spec; + unsigned int pixel; +#endif +{ +register int i; +register XkbColorPtr color; + + if ((!geom)||(!spec)) + return NULL; + for (i=0,color=geom->colors;i<geom->num_colors;i++,color++) { + if ((color->spec)&&(strcmp(color->spec,spec)==0)) { + color->pixel= pixel; + return color; + } + } + if ((geom->num_colors>=geom->sz_colors)&& + (_XkbAllocColors(geom,1)!=Success)) { + return NULL; + } + color= &geom->colors[geom->num_colors]; + color->pixel= pixel; + color->spec= (char *)_XkbAlloc(strlen(spec)+1); + if (!color->spec) + return NULL; + strcpy(color->spec,spec); + geom->num_colors++; + return color; +} + +XkbOutlinePtr +#if NeedFunctionPrototypes +XkbAddGeomOutline(XkbShapePtr shape,int sz_points) +#else +XkbAddGeomOutline(shape,sz_points) + XkbShapePtr shape; + int sz_points; +#endif +{ +XkbOutlinePtr outline; + + if ((!shape)||(sz_points<0)) + return NULL; + if ((shape->num_outlines>=shape->sz_outlines)&& + (_XkbAllocOutlines(shape,1)!=Success)) { + return NULL; + } + outline= &shape->outlines[shape->num_outlines]; + bzero(outline,sizeof(XkbOutlineRec)); + if ((sz_points>0)&&(_XkbAllocPoints(outline,sz_points)!=Success)) + return NULL; + shape->num_outlines++; + return outline; +} + +XkbShapePtr +#if NeedFunctionPrototypes +XkbAddGeomShape(XkbGeometryPtr geom,Atom name,int sz_outlines) +#else +XkbAddGeomShape(geom,name,sz_outlines) + XkbGeometryPtr geom; + Atom name; + int sz_outlines; +#endif +{ +XkbShapePtr shape; +register int i; + + if ((!geom)||(!name)||(sz_outlines<0)) + return NULL; + if (geom->num_shapes>0) { + for (shape=geom->shapes,i=0;i<geom->num_shapes;i++,shape++) { + if (name==shape->name) + return shape; + } + } + if ((geom->num_shapes>=geom->sz_shapes)&& + (_XkbAllocShapes(geom,1)!=Success)) + return NULL; + shape= &geom->shapes[geom->num_shapes]; + bzero(shape,sizeof(XkbShapeRec)); + if ((sz_outlines>0)&&(_XkbAllocOutlines(shape,sz_outlines)!=Success)) + return NULL; + shape->name= name; + shape->primary= shape->approx= NULL; + geom->num_shapes++; + return shape; +} + +XkbKeyPtr +#if NeedFunctionPrototypes +XkbAddGeomKey(XkbRowPtr row) +#else +XkbAddGeomKey(row) + XkbRowPtr row; +#endif +{ +XkbKeyPtr key; + if (!row) + return NULL; + if ((row->num_keys>=row->sz_keys)&&(_XkbAllocKeys(row,1)!=Success)) + return NULL; + key= &row->keys[row->num_keys++]; + bzero(key,sizeof(XkbKeyRec)); + return key; +} + +XkbRowPtr +#if NeedFunctionPrototypes +XkbAddGeomRow(XkbSectionPtr section,int sz_keys) +#else +XkbAddGeomRow(section,sz_keys) + XkbSectionPtr section; + int sz_keys; +#endif +{ +XkbRowPtr row; + + if ((!section)||(sz_keys<0)) + return NULL; + if ((section->num_rows>=section->sz_rows)&& + (_XkbAllocRows(section,1)!=Success)) + return NULL; + row= §ion->rows[section->num_rows]; + bzero(row,sizeof(XkbRowRec)); + if ((sz_keys>0)&&(_XkbAllocKeys(row,sz_keys)!=Success)) + return NULL; + section->num_rows++; + return row; +} + +XkbSectionPtr +#if NeedFunctionPrototypes +XkbAddGeomSection( XkbGeometryPtr geom, + Atom name, + int sz_rows, + int sz_doodads, + int sz_over) +#else +XkbAddGeomSection(geom,name,sz_rows,sz_doodads,sz_over) + XkbGeometryPtr geom; + Atom name; + int sz_rows; + int sz_doodads; + int sz_over; +#endif +{ +register int i; +XkbSectionPtr section; + + if ((!geom)||(name==None)||(sz_rows<0)) + return NULL; + for (i=0,section=geom->sections;i<geom->num_sections;i++,section++) { + if (section->name!=name) + continue; + if (((sz_rows>0)&&(_XkbAllocRows(section,sz_rows)!=Success))|| + ((sz_doodads>0)&&(_XkbAllocDoodads(section,sz_doodads)!=Success))|| + ((sz_over>0)&&(_XkbAllocOverlays(section,sz_over)!=Success))) + return NULL; + return section; + } + if ((geom->num_sections>=geom->sz_sections)&& + (_XkbAllocSections(geom,1)!=Success)) + return NULL; + section= &geom->sections[geom->num_sections]; + if ((sz_rows>0)&&(_XkbAllocRows(section,sz_rows)!=Success)) + return NULL; + if ((sz_doodads>0)&&(_XkbAllocDoodads(section,sz_doodads)!=Success)) { + if (section->rows) { + _XkbFree(section->rows); + section->rows= NULL; + section->sz_rows= section->num_rows= 0; + } + return NULL; + } + section->name= name; + geom->num_sections++; + return section; +} + +XkbDoodadPtr +#if NeedFunctionPrototypes +XkbAddGeomDoodad(XkbGeometryPtr geom,XkbSectionPtr section,Atom name) +#else +XkbAddGeomDoodad(geom,section,name) + XkbGeometryPtr geom; + XkbSectionPtr section; + Atom name; +#endif +{ +XkbDoodadPtr old,doodad; +register int i,nDoodads; + + if ((!geom)||(name==None)) + return NULL; + if ((section!=NULL)&&(section->num_doodads>0)) { + old= section->doodads; + nDoodads= section->num_doodads; + } + else { + old= geom->doodads; + nDoodads= geom->num_doodads; + } + for (i=0,doodad=old;i<nDoodads;i++,doodad++) { + if (doodad->any.name==name) + return doodad; + } + if (section) { + if ((section->num_doodads>=geom->sz_doodads)&& + (_XkbAllocDoodads(section,1)!=Success)) { + return NULL; + } + doodad= §ion->doodads[section->num_doodads++]; + } + else { + if ((geom->num_doodads>=geom->sz_doodads)&& + (_XkbAllocDoodads(geom,1)!=Success)) + return NULL; + doodad= &geom->doodads[geom->num_doodads++]; + } + bzero(doodad,sizeof(XkbDoodadRec)); + doodad->any.name= name; + return doodad; +} + +XkbOverlayKeyPtr +#if NeedFunctionPrototypes +XkbAddGeomOverlayKey( XkbOverlayPtr overlay, + XkbOverlayRowPtr row, + char * over, + char * under) +#else +XkbAddGeomOverlayKey(overlay,row,over,under) + XkbOverlayPtr overlay; + XkbOverlayRowPtr row; + char * over; + char * under; +#endif +{ +register int i; +XkbOverlayKeyPtr key; +XkbSectionPtr section; +XkbRowPtr row_under; +Bool found; + + if ((!overlay)||(!row)||(!over)||(!under)) + return NULL; + section= overlay->section_under; + if (row->row_under>=section->num_rows) + return NULL; + row_under= §ion->rows[row->row_under]; + for (i=0,found=False;i<row_under->num_keys;i++) { + if (strncmp(under,row_under->keys[i].name.name,XkbKeyNameLength)==0) { + found= True; + break; + } + } + if (!found) + return NULL; + if ((row->num_keys>=row->sz_keys)&&(_XkbAllocOverlayKeys(row,1)!=Success)) + return NULL; + key= &row->keys[row->num_keys]; + strncpy(key->under.name,under,XkbKeyNameLength); + strncpy(key->over.name,over,XkbKeyNameLength); + row->num_keys++; + return key; +} + +XkbOverlayRowPtr +#if NeedFunctionPrototypes +XkbAddGeomOverlayRow(XkbOverlayPtr overlay,int row_under,int sz_keys) +#else +XkbAddGeomOverlayRow(overlay,row_under,sz_keys) + XkbOverlayPtr overlay; + int row_under; + int sz_keys; +#endif +{ +register int i; +XkbOverlayRowPtr row; + + if ((!overlay)||(sz_keys<0)) + return NULL; + if (row_under>=overlay->section_under->num_rows) + return NULL; + for (i=0;i<overlay->num_rows;i++) { + if (overlay->rows[i].row_under==row_under) { + row= &overlay->rows[i]; + if ((row->sz_keys<sz_keys)&& + (_XkbAllocOverlayKeys(row,sz_keys)!=Success)) { + return NULL; + } + return &overlay->rows[i]; + } + } + if ((overlay->num_rows>=overlay->sz_rows)&& + (_XkbAllocOverlayRows(overlay,1)!=Success)) + return NULL; + row= &overlay->rows[overlay->num_rows]; + bzero(row,sizeof(XkbOverlayRowRec)); + if ((sz_keys>0)&&(_XkbAllocOverlayKeys(row,sz_keys)!=Success)) + return NULL; + row->row_under= row_under; + overlay->num_rows++; + return row; +} + +XkbOverlayPtr +#if NeedFunctionPrototypes +XkbAddGeomOverlay(XkbSectionPtr section,Atom name,int sz_rows) +#else +XkbAddGeomOverlay(section,name,sz_rows) + XkbSectionPtr section; + Atom name; + int sz_rows; +#endif +{ +register int i; +XkbOverlayPtr overlay; + + if ((!section)||(name==None)||(sz_rows==0)) + return NULL; + + for (i=0,overlay=section->overlays;i<section->num_overlays;i++,overlay++) { + if (overlay->name==name) { + if ((sz_rows>0)&&(_XkbAllocOverlayRows(overlay,sz_rows)!=Success)) + return NULL; + return overlay; + } + } + if ((section->num_overlays>=section->sz_overlays)&& + (_XkbAllocOverlays(section,1)!=Success)) + return NULL; + overlay= §ion->overlays[section->num_overlays]; + if ((sz_rows>0)&&(_XkbAllocOverlayRows(overlay,sz_rows)!=Success)) + return NULL; + overlay->name= name; + overlay->section_under= section; + section->num_overlays++; + return overlay; +} diff --git a/src/xkb/XKBGeom.c b/src/xkb/XKBGeom.c new file mode 100644 index 00000000..5cdd6b99 --- /dev/null +++ b/src/xkb/XKBGeom.c @@ -0,0 +1,779 @@ +/* $Xorg: XKBGeom.c,v 1.4 2000/08/17 19:45:01 cpqbld Exp $ */ +/************************************************************ +Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc. + +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 Silicon Graphics not be +used in advertising or publicity pertaining to distribution +of the software without specific prior written permission. +Silicon Graphics makes no representation about the suitability +of this software for any purpose. It is provided "as is" +without any express or implied warranty. + +SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS +SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON +GRAPHICS 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 DEBUG +#include <stdio.h> +#endif + +#define NEED_EVENTS +#define NEED_REPLIES +#include "Xlibint.h" +#include "XKBlibint.h" +#include <X11/extensions/XKBgeom.h> +#include <X11/extensions/XKBproto.h> + +#ifndef MINSHORT +#define MINSHORT -32768 +#endif +#ifndef MAXSHORT +#define MAXSHORT 32767 +#endif + +/***====================================================================***/ + +static void +#if NeedFunctionPrototypes +_XkbCheckBounds(XkbBoundsPtr bounds,int x,int y) +#else +_XkbCheckBounds(bounds,x,y) + XkbBoundsPtr bounds; + int x,y; +#endif +{ + if (x<bounds->x1) bounds->x1= x; + if (x>bounds->x2) bounds->x2= x; + if (y<bounds->y1) bounds->y1= y; + if (y>bounds->y2) bounds->y2= y; + return; +} + +Bool +#if NeedFunctionPrototypes +XkbComputeShapeBounds(XkbShapePtr shape) +#else +XkbComputeShapeBounds(shape) + XkbShapePtr shape; +#endif +{ +register int o,p; +XkbOutlinePtr outline; +XkbPointPtr pt; + + if ((!shape)||(shape->num_outlines<1)) + return False; + shape->bounds.x1= shape->bounds.y1= MAXSHORT; + shape->bounds.x2= shape->bounds.y2= MINSHORT; + for (outline=shape->outlines,o=0;o<shape->num_outlines;o++,outline++) { + for (pt=outline->points,p=0;p<outline->num_points;p++,pt++) { + _XkbCheckBounds(&shape->bounds,pt->x,pt->y); + } + } + return True; +} + +Bool +#if NeedFunctionPrototypes +XkbComputeShapeTop(XkbShapePtr shape,XkbBoundsPtr bounds) +#else +XkbComputeShapeTop(shape,bounds) + XkbShapePtr shape; + XkbBoundsPtr bounds; +#endif +{ +register int p; +XkbOutlinePtr outline; +XkbPointPtr pt; + + if ((!shape)||(shape->num_outlines<1)) + return False; + if (shape->approx) outline= shape->approx; + else outline= &shape->outlines[shape->num_outlines-1]; + if (outline->num_points<2) { + bounds->x1= bounds->y1= 0; + bounds->x2= bounds->y2= 0; + } + else { + bounds->x1= bounds->y1= MAXSHORT; + bounds->x2= bounds->y2= MINSHORT; + } + for (pt=outline->points,p=0;p<outline->num_points;p++,pt++) { + _XkbCheckBounds(bounds,pt->x,pt->y); + } + return True; +} + +Bool +#if NeedFunctionPrototypes +XkbComputeRowBounds(XkbGeometryPtr geom,XkbSectionPtr section,XkbRowPtr row) +#else +XkbComputeRowBounds(geom,section,row) + XkbGeometryPtr geom; + XkbSectionPtr section; + XkbRowPtr row; +#endif +{ +register int k,pos; +XkbKeyPtr key; +XkbBoundsPtr bounds,sbounds; + + if ((!geom)||(!section)||(!row)) + return False; + pos= 0; + bounds= &row->bounds; + bzero(bounds,sizeof(XkbBoundsRec)); + for (key=row->keys,pos=k=0;k<row->num_keys;k++,key++) { + sbounds= &XkbKeyShape(geom,key)->bounds; + _XkbCheckBounds(bounds,pos,0); + if (!row->vertical) { + if (key->gap!=0) { + pos+= key->gap; + _XkbCheckBounds(bounds,pos,0); + } + _XkbCheckBounds(bounds,pos+sbounds->x1,sbounds->y1); + _XkbCheckBounds(bounds,pos+sbounds->x2,sbounds->y2); + pos+= sbounds->x2; + } + else { + if (key->gap!=0) { + pos+= key->gap; + _XkbCheckBounds(bounds,0,pos); + } + _XkbCheckBounds(bounds,pos+sbounds->x1,sbounds->y1); + _XkbCheckBounds(bounds,pos+sbounds->x2,sbounds->y2); + pos+= sbounds->y2; + } + } + return True; +} + +Bool +#if NeedFunctionPrototypes +XkbComputeSectionBounds(XkbGeometryPtr geom,XkbSectionPtr section) +#else +XkbComputeSectionBounds(geom,section) + XkbGeometryPtr geom; + XkbSectionPtr section; +#endif +{ +register int i; +XkbShapePtr shape; +XkbRowPtr row; +XkbDoodadPtr doodad; +XkbBoundsPtr bounds,rbounds; + + if ((!geom)||(!section)) + return False; + bounds= §ion->bounds; + bzero(bounds,sizeof(XkbBoundsRec)); + for (i=0,row=section->rows;i<section->num_rows;i++,row++) { + if (!XkbComputeRowBounds(geom,section,row)) + return False; + rbounds= &row->bounds; + _XkbCheckBounds(bounds,row->left+rbounds->x1,row->top+rbounds->y1); + _XkbCheckBounds(bounds,row->left+rbounds->x2,row->top+rbounds->y2); + } + for (i=0,doodad=section->doodads;i<section->num_doodads;i++,doodad++) { + static XkbBoundsRec tbounds; + switch (doodad->any.type) { + case XkbOutlineDoodad: + case XkbSolidDoodad: + shape= XkbShapeDoodadShape(geom,&doodad->shape); + rbounds= &shape->bounds; + break; + case XkbTextDoodad: + tbounds.x1= doodad->text.left; + tbounds.y1= doodad->text.top; + tbounds.x2= tbounds.x1+doodad->text.width; + tbounds.y2= tbounds.y1+doodad->text.height; + rbounds= &tbounds; + break; + case XkbIndicatorDoodad: + shape= XkbIndicatorDoodadShape(geom,&doodad->indicator); + rbounds= &shape->bounds; + break; + case XkbLogoDoodad: + shape= XkbLogoDoodadShape(geom,&doodad->logo); + rbounds= &shape->bounds; + break; + default: + tbounds.x1= tbounds.x2= doodad->any.left; + tbounds.y1= tbounds.y2= doodad->any.top; + break; + } + _XkbCheckBounds(bounds,rbounds->x1,rbounds->y1); + _XkbCheckBounds(bounds,rbounds->x2,rbounds->y2); + } + return True; +} + +/***====================================================================***/ + +char * +#if NeedFunctionPrototypes +XkbFindOverlayForKey(XkbGeometryPtr geom,XkbSectionPtr wanted,char *under) +#else +XkbFindOverlayForKey(geom,wanted,under) + XkbGeometryPtr geom; + XkbSectionPtr wanted; + char * under; +#endif +{ +int s; +XkbSectionPtr section; + + if ((geom==NULL)||(under==NULL)||(geom->num_sections<1)) + return NULL; + + if (wanted) + section= wanted; + else section= geom->sections; + + for (s=0;s<geom->num_sections;s++,section++) { + XkbOverlayPtr ol; + int o; + + if (section->num_overlays<1) + continue; + for (o=0,ol=section->overlays;o<section->num_overlays;o++,ol++) { + XkbOverlayRowPtr row; + int r; + + for (r=0,row=ol->rows;r<ol->num_rows;r++,row++) { + XkbOverlayKeyPtr key; + int k; + for (k=0,key=row->keys;k<row->num_keys;k++,key++) { + if (strncmp(under,key->under.name,XkbKeyNameLength)==0) + return key->over.name; + } + } + } + if (wanted!=NULL) + break; + } + return NULL; +} + +/***====================================================================***/ + +static Status +#if NeedFunctionPrototypes +_XkbReadGeomProperties( XkbReadBufferPtr buf, + XkbGeometryPtr geom, + xkbGetGeometryReply * rep) +#else +_XkbReadGeomProperties(buf,geom,rep) + XkbReadBufferPtr buf; + XkbGeometryPtr geom; + xkbGetGeometryReply * rep; +#endif +{ +Status rtrn; + + if (rep->nProperties<1) + return Success; + if ((rtrn=XkbAllocGeomProps(geom,rep->nProperties))==Success) { + register int i; + register Bool ok; + char *name,*value; + ok= True; + for (i=0;(i<rep->nProperties)&&ok;i++) { + ok= _XkbGetReadBufferCountedString(buf,&name)&&ok; + ok= _XkbGetReadBufferCountedString(buf,&value)&&ok; + ok= ok&&(XkbAddGeomProperty(geom,name,value)!=NULL); + } + if (ok) rtrn= Success; + else rtrn= BadLength; + } + return rtrn; +} + +static Status +#if NeedFunctionPrototypes +_XkbReadGeomKeyAliases( XkbReadBufferPtr buf, + XkbGeometryPtr geom, + xkbGetGeometryReply * rep) +#else +_XkbReadGeomKeyAliases(buf,geom,rep) + XkbReadBufferPtr buf; + XkbGeometryPtr geom; + xkbGetGeometryReply * rep; +#endif +{ +Status rtrn; + + if (rep->nKeyAliases<1) + return Success; + if ((rtrn=XkbAllocGeomKeyAliases(geom,rep->nKeyAliases))==Success) { + if (!_XkbCopyFromReadBuffer(buf,(char *)geom->key_aliases, + (rep->nKeyAliases*XkbKeyNameLength*2))) + return BadLength; + geom->num_key_aliases= rep->nKeyAliases; + return Success; + } + else { /* alloc failed, just skip the aliases */ + _XkbSkipReadBufferData(buf,(rep->nKeyAliases*XkbKeyNameLength*2)); + } + return rtrn; +} + +static Status +#if NeedFunctionPrototypes +_XkbReadGeomColors( XkbReadBufferPtr buf, + XkbGeometryPtr geom, + xkbGetGeometryReply * rep) +#else +_XkbReadGeomColors(buf,geom,rep) + XkbReadBufferPtr buf; + XkbGeometryPtr geom; + xkbGetGeometryReply * rep; +#endif +{ +Status rtrn; + + if (rep->nColors<1) + return Success; + if ((rtrn=XkbAllocGeomColors(geom,rep->nColors))==Success) { + register int i; + char *spec; + for (i=0;i<rep->nColors;i++) { + if (!_XkbGetReadBufferCountedString(buf,&spec)) + return BadLength; + if (XkbAddGeomColor(geom,spec,geom->num_colors)==NULL) + return BadAlloc; + } + return Success; + } + return rtrn; +} + +static Status +#if NeedFunctionPrototypes +_XkbReadGeomShapes( XkbReadBufferPtr buf, + XkbGeometryPtr geom, + xkbGetGeometryReply * rep) +#else +_XkbReadGeomShapes(buf,geom,rep) + XkbReadBufferPtr buf; + XkbGeometryPtr geom; + xkbGetGeometryReply * rep; +#endif +{ +register int i; +Status rtrn; + + if (rep->nShapes<1) + return Success; + if ((rtrn=XkbAllocGeomShapes(geom,rep->nShapes))!=Success) + return rtrn; + for (i=0;i<rep->nShapes;i++) { + xkbShapeWireDesc *shapeWire; + XkbShapePtr shape; + register int o; + shapeWire= (xkbShapeWireDesc *) + _XkbGetReadBufferPtr(buf,SIZEOF(xkbShapeWireDesc)); + if (!shapeWire) + return BadLength; + shape= XkbAddGeomShape(geom,shapeWire->name,shapeWire->nOutlines); + if (!shape) + return BadAlloc; + for (o=0;o<shapeWire->nOutlines;o++) { + xkbOutlineWireDesc *olWire; + XkbOutlinePtr ol; + register int p; + XkbPointPtr pt; + olWire= (xkbOutlineWireDesc *) + _XkbGetReadBufferPtr(buf,SIZEOF(xkbOutlineWireDesc)); + if (!olWire) + return BadLength; + ol= XkbAddGeomOutline(shape,olWire->nPoints); + if (!ol) + return BadAlloc; + ol->corner_radius= olWire->cornerRadius; + for (p=0,pt=ol->points;p<olWire->nPoints;p++,pt++) { + xkbPointWireDesc * ptWire; + ptWire= (xkbPointWireDesc *) + _XkbGetReadBufferPtr(buf,SIZEOF(xkbPointWireDesc)); + if (!ptWire) + return BadLength; + pt->x= ptWire->x; + pt->y= ptWire->y; + } + ol->num_points= olWire->nPoints; + } + if (shapeWire->primaryNdx!=XkbNoShape) + shape->primary= &shape->outlines[shapeWire->primaryNdx]; + else shape->primary= NULL; + if (shapeWire->approxNdx!=XkbNoShape) + shape->approx= &shape->outlines[shapeWire->approxNdx]; + else shape->approx= NULL; + XkbComputeShapeBounds(shape); + } + return Success; +} + +static Status +#if NeedFunctionPrototypes +_XkbReadGeomDoodad( XkbReadBufferPtr buf, + XkbGeometryPtr geom, + XkbSectionPtr section) +#else +_XkbReadGeomDoodad(buf,geom,section) + XkbReadBufferPtr buf; + XkbGeometryPtr geom; + XkbSectionPtr section; +#endif +{ +XkbDoodadPtr doodad; +xkbDoodadWireDesc * doodadWire; + + doodadWire= (xkbDoodadWireDesc *) + _XkbGetReadBufferPtr(buf,SIZEOF(xkbDoodadWireDesc)); + if (!doodadWire) + return BadLength; + doodad= XkbAddGeomDoodad(geom,section,doodadWire->any.name); + if (!doodad) + return BadAlloc; + doodad->any.type= doodadWire->any.type; + doodad->any.priority= doodadWire->any.priority; + doodad->any.top= doodadWire->any.top; + doodad->any.left= doodadWire->any.left; + doodad->any.angle= doodadWire->any.angle; + switch (doodad->any.type) { + case XkbOutlineDoodad: + case XkbSolidDoodad: + doodad->shape.color_ndx= doodadWire->shape.colorNdx; + doodad->shape.shape_ndx= doodadWire->shape.shapeNdx; + break; + case XkbTextDoodad: + doodad->text.width= doodadWire->text.width; + doodad->text.height= doodadWire->text.height; + doodad->text.color_ndx= doodadWire->text.colorNdx; + if (!_XkbGetReadBufferCountedString(buf,&doodad->text.text)) + return BadLength; + if (!_XkbGetReadBufferCountedString(buf,&doodad->text.font)) + return BadLength; + break; + case XkbIndicatorDoodad: + doodad->indicator.shape_ndx= doodadWire->indicator.shapeNdx; + doodad->indicator.on_color_ndx= doodadWire->indicator.onColorNdx; + doodad->indicator.off_color_ndx= doodadWire->indicator.offColorNdx; + break; + case XkbLogoDoodad: + doodad->logo.color_ndx= doodadWire->logo.colorNdx; + doodad->logo.shape_ndx= doodadWire->logo.shapeNdx; + if (!_XkbGetReadBufferCountedString(buf,&doodad->logo.logo_name)) + return BadLength; + break; + default: + return BadValue; + } + return Success; +} + +static Status +#if NeedFunctionPrototypes +_XkbReadGeomOverlay( XkbReadBufferPtr buf, + XkbGeometryPtr geom, + XkbSectionPtr section) +#else +_XkbReadGeomOverlay(buf,geom,section) + XkbReadBufferPtr buf; + XkbGeometryPtr geom; + XkbSectionPtr section; +#endif +{ +XkbOverlayPtr ol; +xkbOverlayWireDesc * olWire; +register int r; + + olWire= (xkbOverlayWireDesc *) + _XkbGetReadBufferPtr(buf,SIZEOF(xkbOverlayWireDesc)); + if (olWire==NULL) + return BadLength; + ol= XkbAddGeomOverlay(section,olWire->name,olWire->nRows); + if (ol==NULL) + return BadLength; + for (r=0;r<olWire->nRows;r++) { + register int k; + XkbOverlayRowPtr row; + xkbOverlayRowWireDesc * rowWire; + xkbOverlayKeyWireDesc * keyWire; + rowWire= (xkbOverlayRowWireDesc *) + _XkbGetReadBufferPtr(buf,SIZEOF(xkbOverlayRowWireDesc)); + if (rowWire==NULL) + return BadLength; + row= XkbAddGeomOverlayRow(ol,rowWire->rowUnder,rowWire->nKeys); + row->row_under= rowWire->rowUnder; + if (!row) + return BadAlloc; + if (rowWire->nKeys<1) + continue; + keyWire= (xkbOverlayKeyWireDesc *) + _XkbGetReadBufferPtr(buf, + SIZEOF(xkbOverlayKeyWireDesc)*rowWire->nKeys); + if (keyWire==NULL) + return BadLength; + for (k=0;k<rowWire->nKeys;k++,keyWire++,row->num_keys++) { + memcpy(row->keys[row->num_keys].over.name,keyWire->over, + XkbKeyNameLength); + memcpy(row->keys[row->num_keys].under.name,keyWire->under, + XkbKeyNameLength); + } + } + return Success; +} + +static Status +#if NeedFunctionPrototypes +_XkbReadGeomSections( XkbReadBufferPtr buf, + XkbGeometryPtr geom, + xkbGetGeometryReply * rep) +#else +_XkbReadGeomSections(buf,geom,rep) + XkbReadBufferPtr buf; + XkbGeometryPtr geom; + xkbGetGeometryReply * rep; +#endif +{ +register int s; +XkbSectionPtr section; +xkbSectionWireDesc * sectionWire; +Status rtrn; + + if (rep->nSections<1) + return Success; + if ((rtrn=XkbAllocGeomSections(geom,rep->nSections))!=Success) + return rtrn; + for (s=0;s<rep->nSections;s++) { + sectionWire= (xkbSectionWireDesc *) + _XkbGetReadBufferPtr(buf,SIZEOF(xkbSectionWireDesc)); + if (!sectionWire) + return BadLength; + section= XkbAddGeomSection(geom,sectionWire->name,sectionWire->nRows, + sectionWire->nDoodads, + sectionWire->nOverlays); + if (!section) + return BadAlloc; + section->top= sectionWire->top; + section->left= sectionWire->left; + section->width= sectionWire->width; + section->height= sectionWire->height; + section->angle= sectionWire->angle; + section->priority= sectionWire->priority; + if (sectionWire->nRows>0) { + register int r; + XkbRowPtr row; + xkbRowWireDesc * rowWire; + for (r=0;r<sectionWire->nRows;r++) { + rowWire= (xkbRowWireDesc *) + _XkbGetReadBufferPtr(buf,SIZEOF(xkbRowWireDesc)); + if (!rowWire) + return BadLength; + row= XkbAddGeomRow(section,rowWire->nKeys); + if (!row) + return BadAlloc; + row->top= rowWire->top; + row->left= rowWire->left; + row->vertical= rowWire->vertical; + if (rowWire->nKeys>0) { + register int k; + XkbKeyPtr key; + xkbKeyWireDesc * keyWire; + for (k=0;k<rowWire->nKeys;k++) { + keyWire= (xkbKeyWireDesc *) + _XkbGetReadBufferPtr(buf,SIZEOF(xkbKeyWireDesc)); + if (!keyWire) + return BadLength; + key= XkbAddGeomKey(row); + if (!key) + return BadAlloc; + memcpy(key->name.name,keyWire->name,XkbKeyNameLength); + key->gap= keyWire->gap; + key->shape_ndx= keyWire->shapeNdx; + key->color_ndx= keyWire->colorNdx; + } + } + } + } + if (sectionWire->nDoodads>0) { + register int d; + for (d=0;d<sectionWire->nDoodads;d++) { + if ((rtrn=_XkbReadGeomDoodad(buf,geom,section))!=Success) + return rtrn; + } + } + if (sectionWire->nOverlays>0) { + register int o; + for (o=0;o<sectionWire->nOverlays;o++) { + if ((rtrn=_XkbReadGeomOverlay(buf,geom,section))!=Success) + return rtrn; + } + } + } + return Success; +} + +static Status +#if NeedFunctionPrototypes +_XkbReadGeomDoodads( XkbReadBufferPtr buf, + XkbGeometryPtr geom, + xkbGetGeometryReply * rep) +#else +_XkbReadGeomDoodads(buf,geom,rep) + XkbReadBufferPtr buf; + XkbGeometryPtr geom; + xkbGetGeometryReply * rep; +#endif +{ +register int d; +Status rtrn; + + if (rep->nDoodads<1) + return Success; + if ((rtrn=XkbAllocGeomDoodads(geom,rep->nDoodads))!=Success) + return rtrn; + for (d=0;d<rep->nDoodads;d++) { + if ((rtrn=_XkbReadGeomDoodad(buf,geom,NULL))!=Success) + return rtrn; + } + return Success; +} + +Status +#if NeedFunctionPrototypes +_XkbReadGetGeometryReply( Display * dpy, + xkbGetGeometryReply * rep, + XkbDescPtr xkb, + int * nread_rtrn) +#else +_XkbReadGetGeometryReply(dpy,rep,xkb,nread_rtrn) + Display * dpy; + xkbGetGeometryReply * rep; + XkbDescPtr xkb; + int * nread_rtrn; +#endif +{ +XkbGeometryPtr geom; + + geom= _XkbTypedCalloc(1,XkbGeometryRec); + if (!geom) + return BadAlloc; + if (xkb->geom) + XkbFreeGeometry(xkb->geom,XkbGeomAllMask,True); + xkb->geom= geom; + + geom->name= rep->name; + geom->width_mm= rep->widthMM; + geom->height_mm= rep->heightMM; + if (rep->length) { + XkbReadBufferRec buf; + int left; + if (_XkbInitReadBuffer(dpy,&buf,(int)rep->length*4)) { + Status status= Success; + if (nread_rtrn) + *nread_rtrn= (int)rep->length*4; + if (!_XkbGetReadBufferCountedString(&buf,&geom->label_font)) + status= BadLength; + if (status==Success) + status= _XkbReadGeomProperties(&buf,geom,rep); + if (status==Success) + status= _XkbReadGeomColors(&buf,geom,rep); + if (status==Success) + status= _XkbReadGeomShapes(&buf,geom,rep); + if (status==Success) + status= _XkbReadGeomSections(&buf,geom,rep); + if (status==Success) + status= _XkbReadGeomDoodads(&buf,geom,rep); + if (status==Success) + status= _XkbReadGeomKeyAliases(&buf,geom,rep); + left= _XkbFreeReadBuffer(&buf); + if ((status!=Success) || left || buf.error) { + if (status==Success) + status= BadLength; + XkbFreeGeometry(geom,XkbGeomAllMask,True); + xkb->geom= NULL; + return status; + } + geom->base_color= &geom->colors[rep->baseColorNdx]; + geom->label_color= &geom->colors[rep->labelColorNdx]; + } + else { + XkbFreeGeometry(geom,XkbGeomAllMask,True); + xkb->geom= NULL; + return BadAlloc; + } + } + return Success; +} + +Status +#if NeedFunctionPrototypes +XkbGetGeometry(Display *dpy,XkbDescPtr xkb) +#else +XkbGetGeometry(dpy,xkb) + Display * dpy; + XkbDescPtr xkb; +#endif +{ +xkbGetGeometryReq *req; +xkbGetGeometryReply rep; + + if ( (!xkb) || (dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) + return BadAccess; + + GetReq(kbGetGeometry, req); + req->reqType = dpy->xkb_info->codes->major_opcode; + req->xkbReqType = X_kbGetGeometry; + req->deviceSpec = xkb->device_spec; + req->name= None; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) + return BadImplementation; + if (!rep.found) + return BadName; + return _XkbReadGetGeometryReply(dpy,&rep,xkb,NULL); +} + +Status +#if NeedFunctionPrototypes +XkbGetNamedGeometry(Display *dpy,XkbDescPtr xkb,Atom name) +#else +XkbGetNamedGeometry(dpy,xkb,name) + Display * dpy; + XkbDescPtr xkb; + Atom name; +#endif +{ +xkbGetGeometryReq *req; +xkbGetGeometryReply rep; + + if ( (name==None) || (dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL)) ) + return BadAccess; + + GetReq(kbGetGeometry, req); + req->reqType = dpy->xkb_info->codes->major_opcode; + req->xkbReqType = X_kbGetGeometry; + req->deviceSpec = xkb->device_spec; + req->name= (CARD32)name; + if ((!_XReply(dpy, (xReply *)&rep, 0, xFalse))||(!rep.found)) + return BadImplementation; + if (!rep.found) + return BadName; + return _XkbReadGetGeometryReply(dpy,&rep,xkb,NULL); +} + diff --git a/src/xkb/XKBGetByName.c b/src/xkb/XKBGetByName.c new file mode 100644 index 00000000..411be961 --- /dev/null +++ b/src/xkb/XKBGetByName.c @@ -0,0 +1,231 @@ +/* $Xorg: XKBGetByName.c,v 1.3 2000/08/17 19:45:02 cpqbld Exp $ */ +/************************************************************ +Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc. + +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 Silicon Graphics not be +used in advertising or publicity pertaining to distribution +of the software without specific prior written permission. +Silicon Graphics makes no representation about the suitability +of this software for any purpose. It is provided "as is" +without any express or implied warranty. + +SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS +SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON +GRAPHICS 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. + +********************************************************/ + +#define NEED_REPLIES +#define NEED_EVENTS +#define NEED_MAP_READERS +#include "Xlibint.h" +#include <X11/extensions/XKBproto.h> +#include "XKBlibint.h" + +/***====================================================================***/ + +XkbDescPtr +#if NeedFunctionPrototypes +XkbGetKeyboardByName( Display * dpy, + unsigned deviceSpec, + XkbComponentNamesPtr names, + unsigned want, + unsigned need, + Bool load) +#else +XkbGetKeyboardByName(dpy,deviceSpec,names,want,need,load) + Display * dpy; + unsigned deviceSpec; + XkbComponentNamesPtr names; + unsigned want; + unsigned need; + Bool load; +#endif +{ + register xkbGetKbdByNameReq * req; + xkbGetKbdByNameReply rep; + int len,extraLen; + char * str; + XkbDescPtr xkb; + int mapLen,codesLen,typesLen,compatLen; + int symsLen,geomLen; + XkbInfoPtr xkbi; + + if ( (dpy==NULL) || (dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL)) ) + return NULL; + + xkbi= dpy->xkb_info; + xkb = (XkbDescRec *)_XkbCalloc(1,sizeof(XkbDescRec)); + if (!xkb) + return NULL; + xkb->device_spec = deviceSpec; + xkb->map = (XkbClientMapRec *)_XkbCalloc(1,sizeof(XkbClientMapRec)); + xkb->dpy = dpy; + + LockDisplay(dpy); + GetReq(kbGetKbdByName, req); + req->reqType = xkbi->codes->major_opcode; + req->xkbReqType = X_kbGetKbdByName; + req->deviceSpec = xkb->device_spec; + req->want= want; + req->need= need; + req->load= load; + + mapLen= codesLen= typesLen= compatLen= symsLen= geomLen= 0; + if (names) { + if (names->keymap) + mapLen= (int)strlen(names->keymap); + if (names->keycodes) + codesLen= (int)strlen(names->keycodes); + if (names->types) + typesLen= (int)strlen(names->types); + if (names->compat) + compatLen= (int)strlen(names->compat); + if (names->symbols) + symsLen= (int)strlen(names->symbols); + if (names->geometry) + geomLen= (int)strlen(names->geometry); + if (mapLen>255) mapLen= 255; + if (codesLen>255) codesLen= 255; + if (typesLen>255) typesLen= 255; + if (compatLen>255) compatLen= 255; + if (symsLen>255) symsLen= 255; + if (geomLen>255) geomLen= 255; + } + else mapLen= codesLen= typesLen= compatLen= symsLen= geomLen= 0; + + len= mapLen+codesLen+typesLen+compatLen+symsLen+geomLen+6; + len= XkbPaddedSize(len); + req->length+= len/4; + BufAlloc(char *,str,len); + *str++= mapLen; + if (mapLen>0) { + memcpy(str,names->keymap,mapLen); + str+= mapLen; + } + *str++= codesLen; + if (codesLen>0) { + memcpy(str,names->keycodes,codesLen); + str+= codesLen; + } + *str++= typesLen; + if (typesLen>0) { + memcpy(str,names->types,typesLen); + str+= typesLen; + } + *str++= compatLen; + if (compatLen>0) { + memcpy(str,names->compat,compatLen); + str+= compatLen; + } + *str++= symsLen; + if (symsLen>0) { + memcpy(str,names->symbols,symsLen); + str+= symsLen; + } + *str++= geomLen; + if (geomLen>0) { + memcpy(str,names->geometry,geomLen); + str+= geomLen; + } + if ((!_XReply(dpy, (xReply *)&rep, 0, xFalse))||(!rep.reported)) + goto BAILOUT; + extraLen= (int)rep.length*4; + + xkb->device_spec= rep.deviceID; + xkb->min_key_code = rep.minKeyCode; + xkb->max_key_code = rep.maxKeyCode; + if (rep.reported&(XkbGBN_SymbolsMask|XkbGBN_TypesMask)) { + xkbGetMapReply mrep; + Status status; + int nread= 0; + + _XRead(dpy, (char *)&mrep, SIZEOF(xkbGetMapReply)); + extraLen-= SIZEOF(xkbGetMapReply); + status= _XkbReadGetMapReply(dpy,&mrep,xkb,&nread); + extraLen-= nread; + if (status!=Success) + goto BAILOUT; + } + if (rep.reported&XkbGBN_CompatMapMask) { + xkbGetCompatMapReply crep; + Status status; + int nread= 0; + + _XRead(dpy, (char *)&crep, SIZEOF(xkbGetCompatMapReply)); + extraLen-= SIZEOF(xkbGetCompatMapReply); + status= _XkbReadGetCompatMapReply(dpy,&crep,xkb,&nread); + extraLen-= nread; + if (status!=Success) + goto BAILOUT; + } + if (rep.reported&XkbGBN_IndicatorMapMask) { + xkbGetIndicatorMapReply irep; + Status status; + int nread= 0; + + _XRead(dpy, (char *)&irep, SIZEOF(xkbGetIndicatorMapReply)); + extraLen-= SIZEOF(xkbGetIndicatorMapReply); + status= _XkbReadGetIndicatorMapReply(dpy,&irep,xkb,&nread); + extraLen-= nread; + if (status!=Success) + goto BAILOUT; + } + if (rep.reported&(XkbGBN_KeyNamesMask|XkbGBN_OtherNamesMask)) { + xkbGetNamesReply nrep; + Status status; + int nread= 0; + + _XRead(dpy, (char *)&nrep, SIZEOF(xkbGetNamesReply)); + extraLen-= SIZEOF(xkbGetNamesReply); + status= _XkbReadGetNamesReply(dpy,&nrep,xkb,&nread); + extraLen-= nread; + if (status!=Success) + goto BAILOUT; + } + if (rep.reported&XkbGBN_GeometryMask) { + xkbGetGeometryReply grep; + Status status; + int nread= 0; + + _XRead(dpy, (char *)&grep, SIZEOF(xkbGetGeometryReply)); + extraLen-= SIZEOF(xkbGetGeometryReply); + status= _XkbReadGetGeometryReply(dpy,&grep,xkb,&nread); + extraLen-= nread; + if (status!=Success) + goto BAILOUT; + } + UnlockDisplay(dpy); + SyncHandle(); + return xkb; +BAILOUT: + if (xkb!=NULL) + XkbFreeKeyboard(xkb,XkbAllComponentsMask,xTrue); + UnlockDisplay(dpy); + SyncHandle(); + return NULL; +} + +XkbDescPtr +#if NeedFunctionPrototypes +XkbGetKeyboard(Display *dpy,unsigned which,unsigned deviceSpec) +#else +XkbGetKeyboard(dpy,which,deviceSpec) + Display * dpy; + unsigned which; + unsigned deviceSpec; +#endif +{ + return XkbGetKeyboardByName(dpy,deviceSpec,NULL,which,which,False); +} diff --git a/src/xkb/XKBGetMap.c b/src/xkb/XKBGetMap.c new file mode 100644 index 00000000..8975ba39 --- /dev/null +++ b/src/xkb/XKBGetMap.c @@ -0,0 +1,975 @@ +/* $Xorg: XKBGetMap.c,v 1.4 2000/08/17 19:45:02 cpqbld Exp $ */ +/************************************************************ +Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc. + +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 Silicon Graphics not be +used in advertising or publicity pertaining to distribution +of the software without specific prior written permission. +Silicon Graphics makes no representation about the suitability +of this software for any purpose. It is provided "as is" +without any express or implied warranty. + +SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS +SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON +GRAPHICS 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. + +********************************************************/ + +#define NEED_REPLIES +#define NEED_EVENTS +#define NEED_MAP_READERS +#include "Xlibint.h" +#include <X11/extensions/XKBproto.h> +#include "XKBlibint.h" + +static Status +#if NeedFunctionPrototypes +_XkbReadKeyTypes(XkbReadBufferPtr buf,XkbDescPtr xkb,xkbGetMapReply *rep) +#else +_XkbReadKeyTypes(buf,xkb,rep) + XkbReadBufferPtr buf; + XkbDescPtr xkb; + xkbGetMapReply * rep; +#endif +{ +int i,n,lastMapCount; +XkbKeyTypePtr type; + + if ( rep->nTypes>0 ) { + n = rep->firstType+rep->nTypes; + if (xkb->map->num_types>=n) + n= xkb->map->num_types; + else if (XkbAllocClientMap(xkb,XkbKeyTypesMask,n)!=Success) + return BadAlloc; + + type = &xkb->map->types[rep->firstType]; + for (i=0;i<(int)rep->nTypes;i++,type++) { + xkbKeyTypeWireDesc *desc; + register int ndx; + + ndx= i+rep->firstType; + if (ndx>=xkb->map->num_types) + xkb->map->num_types= ndx+1; + + desc= (xkbKeyTypeWireDesc *)_XkbGetReadBufferPtr(buf, + SIZEOF(xkbKeyTypeWireDesc)); + if (desc==NULL) + return BadLength; + + lastMapCount= type->map_count; + if ( desc->nMapEntries>0 ) { + if ((type->map==NULL)||(desc->nMapEntries>type->map_count)) { + XkbKTMapEntryRec *prev_map = type->map; + + type->map= _XkbTypedRealloc(type->map,desc->nMapEntries, + XkbKTMapEntryRec); + if (type->map==NULL) { + _XkbFree(prev_map); + return BadAlloc; + } + } + } + else if (type->map!=NULL) { + Xfree(type->map); + type->map_count= 0; + type->map= NULL; + } + + if ( desc->preserve && (desc->nMapEntries>0) ) { + if ((!type->preserve)|| + (desc->nMapEntries>lastMapCount)) { + XkbModsRec *prev_preserve = type->preserve; + + type->preserve= _XkbTypedRealloc(type->preserve, + desc->nMapEntries, + XkbModsRec); + if (type->preserve==NULL) { + _XkbFree(prev_preserve); + return BadAlloc; + } + } + } + else if (type->preserve!=NULL) { + Xfree(type->preserve); + type->preserve= NULL; + } + + type->mods.mask = desc->mask; + type->mods.real_mods = desc->realMods; + type->mods.vmods = desc->virtualMods; + type->num_levels = desc->numLevels; + type->map_count = desc->nMapEntries; + if (desc->nMapEntries>0) { + register xkbKTMapEntryWireDesc *wire; + register XkbKTMapEntryPtr entry; + register int size; + + size= type->map_count*SIZEOF(xkbKTMapEntryWireDesc); + wire= (xkbKTMapEntryWireDesc *)_XkbGetReadBufferPtr(buf,size); + if (wire==NULL) + return BadLength; + entry= type->map; + for (n=0;n<type->map_count;n++,wire++,entry++) { + entry->active= wire->active; + entry->level= wire->level; + entry->mods.mask= wire->mask; + entry->mods.real_mods= wire->realMods; + entry->mods.vmods= wire->virtualMods; + } + + if (desc->preserve) { + register xkbModsWireDesc * pwire; + register XkbModsPtr preserve; + register int sz; + + sz= desc->nMapEntries*SIZEOF(xkbModsWireDesc); + pwire=(xkbModsWireDesc *)_XkbGetReadBufferPtr(buf,sz); + if (pwire==NULL) + return BadLength; + preserve= type->preserve; + for (n=0;n<desc->nMapEntries;n++,pwire++,preserve++) { + preserve->mask= pwire->mask; + preserve->vmods= pwire->virtualMods; + preserve->real_mods= pwire->realMods; + } + } + } + } + } + return Success; +} + +static Status +#if NeedFunctionPrototypes +_XkbReadKeySyms(XkbReadBufferPtr buf,XkbDescPtr xkb,xkbGetMapReply *rep) +#else +_XkbReadKeySyms(buf,xkb,rep) + XkbReadBufferPtr buf; + XkbDescPtr xkb; + xkbGetMapReply * rep; +#endif +{ +register int i; +XkbClientMapPtr map; + + map= xkb->map; + if (map->key_sym_map==NULL) { + register int offset; + XkbSymMapPtr oldMap; + xkbSymMapWireDesc *newMap; + map->key_sym_map= _XkbTypedCalloc((xkb->max_key_code+1),XkbSymMapRec); + if (map->key_sym_map==NULL) + return BadAlloc; + if (map->syms==NULL) { + int sz; + sz= (rep->totalSyms*12)/10; + sz= ((sz+(unsigned)128)/128)*128; + map->syms = _XkbTypedCalloc(sz,KeySym); + if (map->syms==NULL) + return BadAlloc; + map->size_syms = sz; + } + offset = 1; + oldMap = &map->key_sym_map[rep->firstKeySym]; + for (i=0;i<(int)rep->nKeySyms;i++,oldMap++) { + newMap= (xkbSymMapWireDesc *) + _XkbGetReadBufferPtr(buf,SIZEOF(xkbSymMapWireDesc)); + if (newMap==NULL) + return BadLength; + oldMap->kt_index[0]= newMap->ktIndex[0]; + oldMap->kt_index[1]= newMap->ktIndex[1]; + oldMap->kt_index[2]= newMap->ktIndex[2]; + oldMap->kt_index[3]= newMap->ktIndex[3]; + oldMap->group_info= newMap->groupInfo; + oldMap->width= newMap->width; + oldMap->offset= offset; + if (offset+newMap->nSyms>=map->size_syms) { + register int sz; + KeySym *prev_syms = map->syms; + + sz= map->size_syms+128; + map->syms= _XkbTypedRealloc(map->syms,sz,KeySym); + if (map->syms==NULL) { + _XkbFree(prev_syms); + map->size_syms= 0; + return BadAlloc; + } + map->size_syms= sz; + } + if (newMap->nSyms>0) { + _XkbReadBufferCopyKeySyms(buf,(KeySym *)&map->syms[offset], + newMap->nSyms); + offset+= newMap->nSyms; + } + else { + map->syms[offset]= 0; + } + } + map->num_syms= offset; + } + else { + xkbSymMapWireDesc * newMap; + XkbSymMapPtr oldMap; + KeySym * newSyms; + int tmp; + + oldMap = &map->key_sym_map[rep->firstKeySym]; + for (i=0;i<(int)rep->nKeySyms;i++,oldMap++) { + newMap= (xkbSymMapWireDesc *) + _XkbGetReadBufferPtr(buf,SIZEOF(xkbSymMapWireDesc)); + if (newMap==NULL) + return BadLength; + + if (newMap->nSyms>0) + tmp= newMap->nSyms; + else tmp= 0; + + newSyms = XkbResizeKeySyms(xkb,i+rep->firstKeySym,tmp); + if (newSyms==NULL) + return BadAlloc; + if (newMap->nSyms>0) + _XkbReadBufferCopyKeySyms(buf,newSyms,newMap->nSyms); + else newSyms[0]= NoSymbol; + oldMap->kt_index[0] = newMap->ktIndex[0]; + oldMap->kt_index[1] = newMap->ktIndex[1]; + oldMap->kt_index[2] = newMap->ktIndex[2]; + oldMap->kt_index[3] = newMap->ktIndex[3]; + oldMap->group_info = newMap->groupInfo; + oldMap->width = newMap->width; + } + } + return Success; +} + +static Status +#if NeedFunctionPrototypes +_XkbReadKeyActions(XkbReadBufferPtr buf,XkbDescPtr info,xkbGetMapReply *rep) +#else +_XkbReadKeyActions(buf,info,rep) + XkbReadBufferPtr buf; + XkbDescPtr info; + xkbGetMapReply * rep; +#endif +{ +int i; +CARD8 numDescBuf[248]; +CARD8* numDesc = NULL; +register int nKeyActs; +Status ret = Success; + + if ( (nKeyActs=rep->nKeyActs)>0 ) { + XkbSymMapPtr symMap; + + if (nKeyActs < sizeof numDescBuf) numDesc = numDescBuf; + else numDesc = Xmalloc (nKeyActs * sizeof(CARD8)); + + if (!_XkbCopyFromReadBuffer(buf, (char *)numDesc, nKeyActs)) { + ret = BadLength; + goto done; + } + i= XkbPaddedSize(nKeyActs)-nKeyActs; + if ((i>0)&&(!_XkbSkipReadBufferData(buf,i))) { + ret = BadLength; + goto done; + } + symMap = &info->map->key_sym_map[rep->firstKeyAct]; + for (i=0;i<(int)rep->nKeyActs;i++,symMap++) { + if (numDesc[i]==0) { + info->server->key_acts[i+rep->firstKeyAct]= 0; + } + else { + XkbAction *newActs; + /* 8/16/93 (ef) -- XXX! Verify size here (numdesc must be */ + /* either zero or XkbKeyNumSyms(info,key) */ + newActs=XkbResizeKeyActions(info,i+rep->firstKeyAct, + numDesc[i]); + if (newActs==NULL) { + ret = BadAlloc; + goto done; + } + if (!_XkbCopyFromReadBuffer(buf,(char *)newActs, + (int)(numDesc[i]*sizeof(XkbAction)))) { + ret = BadLength; + goto done; + } + } + } + } +done: + if (numDesc != NULL && numDesc != numDescBuf) Xfree (numDesc); + return ret; +} + +static Status +#if NeedFunctionPrototypes +_XkbReadKeyBehaviors(XkbReadBufferPtr buf,XkbDescPtr xkb,xkbGetMapReply *rep) +#else +_XkbReadKeyBehaviors(buf,xkb,rep) + XkbReadBufferPtr buf; + XkbDescPtr xkb; + xkbGetMapReply * rep; +#endif +{ +register int i; +xkbBehaviorWireDesc *wire; + + if ( rep->totalKeyBehaviors>0 ) { + if ( xkb->server->behaviors == NULL ) { + int size = xkb->max_key_code+1; + xkb->server->behaviors = _XkbTypedCalloc(size,XkbBehavior); + if (xkb->server->behaviors==NULL) + return BadAlloc; + } + else { + bzero(&xkb->server->behaviors[rep->firstKeyBehavior], + (rep->nKeyBehaviors*sizeof(XkbBehavior))); + } + for (i=0;i<rep->totalKeyBehaviors;i++) { + wire= (xkbBehaviorWireDesc *)_XkbGetReadBufferPtr(buf, + SIZEOF(xkbBehaviorWireDesc)); + if (wire==NULL) + return BadLength; + xkb->server->behaviors[wire->key].type= wire->type; + xkb->server->behaviors[wire->key].data= wire->data; + } + } + return Success; +} + +static Status +#if NeedFunctionPrototypes +_XkbReadVirtualMods(XkbReadBufferPtr buf,XkbDescPtr xkb,xkbGetMapReply *rep) +#else +_XkbReadVirtualMods(buf,xkb,rep) + XkbReadBufferPtr buf; + XkbDescPtr xkb; + xkbGetMapReply * rep; +#endif +{ + if ( rep->virtualMods ) { + register int i,bit,nVMods; + register char *data; + + for (i=nVMods=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) { + if (rep->virtualMods&bit) + nVMods++; + } + data= _XkbGetReadBufferPtr(buf,XkbPaddedSize(nVMods)); + if (data==NULL) + return BadLength; + for (i=0,bit=1;(i<XkbNumVirtualMods)&&(nVMods>0);i++,bit<<=1) { + if (rep->virtualMods&bit) { + xkb->server->vmods[i]= *data++; + nVMods--; + } + } + } + return Success; +} + +static Status +#if NeedFunctionPrototypes +_XkbReadExplicitComponents( XkbReadBufferPtr buf, + XkbDescPtr xkb, + xkbGetMapReply * rep) +#else +_XkbReadExplicitComponents(buf,xkb,rep) + XkbReadBufferPtr buf; + XkbDescPtr xkb; + xkbGetMapReply * rep; +#endif +{ +register int i; +unsigned char *wire; + + if ( rep->totalKeyExplicit>0 ) { + if ( xkb->server->explicit == NULL ) { + int size = xkb->max_key_code+1; + xkb->server->explicit = _XkbTypedCalloc(size,unsigned char); + if (xkb->server->explicit==NULL) + return BadAlloc; + } + else { + bzero(&xkb->server->explicit[rep->firstKeyExplicit], + rep->nKeyExplicit); + } + i= XkbPaddedSize(2*rep->totalKeyExplicit); + wire=(unsigned char *)_XkbGetReadBufferPtr(buf,i); + if (!wire) + return BadLength; + for (i=0;i<rep->totalKeyExplicit;i++,wire+=2) { + xkb->server->explicit[wire[0]]= wire[1]; + } + } + return Success; +} + +static Status +#if NeedFunctionPrototypes +_XkbReadModifierMap(XkbReadBufferPtr buf,XkbDescPtr xkb,xkbGetMapReply *rep) +#else +_XkbReadModifierMap(buf,xkb,rep) + XkbReadBufferPtr buf; + XkbDescPtr xkb; + xkbGetMapReply * rep; +#endif +{ +register int i; +unsigned char *wire; + + if ( rep->totalModMapKeys>0 ) { + if ((xkb->map->modmap==NULL)&& + (XkbAllocClientMap(xkb,XkbModifierMapMask,0)!=Success)) { + return BadAlloc; + } + else { + bzero(&xkb->map->modmap[rep->firstModMapKey],rep->nModMapKeys); + } + i= XkbPaddedSize(2*rep->totalModMapKeys); + wire=(unsigned char *)_XkbGetReadBufferPtr(buf,i); + if (!wire) + return BadLength; + for (i=0;i<rep->totalModMapKeys;i++,wire+=2) { + xkb->map->modmap[wire[0]]= wire[1]; + } + } + return Success; +} + +static Status +#if NeedFunctionPrototypes +_XkbReadVirtualModMap(XkbReadBufferPtr buf,XkbDescPtr xkb,xkbGetMapReply *rep) +#else +_XkbReadVirtualModMap(buf,xkb,rep) + XkbReadBufferPtr buf; + XkbDescPtr xkb; + xkbGetMapReply * rep; +#endif +{ +register int i; +xkbVModMapWireDesc * wire; +XkbServerMapPtr srv; + + if ( rep->totalVModMapKeys>0 ) { + if (((xkb->server==NULL)||(xkb->server->vmodmap==NULL))&& + (XkbAllocServerMap(xkb,XkbVirtualModMapMask,0)!=Success)) { + return BadAlloc; + } + else { + srv= xkb->server; + bzero((char *)&srv->vmodmap[rep->firstVModMapKey], + rep->nVModMapKeys*sizeof(unsigned short)); + } + srv= xkb->server; + i= rep->totalVModMapKeys*SIZEOF(xkbVModMapWireDesc); + wire=(xkbVModMapWireDesc *)_XkbGetReadBufferPtr(buf,i); + if (!wire) + return BadLength; + for (i=0;i<rep->totalVModMapKeys;i++,wire++) { + if ((wire->key>=xkb->min_key_code)&&(wire->key<=xkb->max_key_code)) + srv->vmodmap[wire->key]= wire->vmods; + } + } + return Success; +} + +static xkbGetMapReq * +#if NeedFunctionPrototypes +_XkbGetGetMapReq(Display *dpy,XkbDescPtr xkb) +#else +_XkbGetGetMapReq(dpy,xkb) + Display * dpy; + XkbDescPtr xkb; +#endif +{ +xkbGetMapReq *req; + + GetReq(kbGetMap, req); + req->reqType = dpy->xkb_info->codes->major_opcode; + req->xkbReqType = X_kbGetMap; + req->deviceSpec = xkb->device_spec; + req->full = req->partial = 0; + req->firstType = req->nTypes = 0; + req->firstKeySym = req->nKeySyms = 0; + req->firstKeyAct = req->nKeyActs = 0; + req->firstKeyBehavior = req->nKeyBehaviors = 0; + req->virtualMods = 0; + req->firstKeyExplicit = req->nKeyExplicit = 0; + req->firstModMapKey = req->nModMapKeys = 0; + req->firstVModMapKey = req->nVModMapKeys = 0; + return req; +} + +Status +#if NeedFunctionPrototypes +_XkbReadGetMapReply( Display * dpy, + xkbGetMapReply *rep, + XkbDescPtr xkb, + int * nread_rtrn) +#else +_XkbReadGetMapReply(dpy,rep,xkb,nread_rtrn) + Display * dpy; + xkbGetMapReply * rep; + XkbDescPtr xkb; + int * nread_rtrn; +#endif +{ +int extraData; +unsigned mask; + + if ( xkb->device_spec == XkbUseCoreKbd ) + xkb->device_spec= rep->deviceID; + xkb->min_key_code = rep->minKeyCode; + xkb->max_key_code = rep->maxKeyCode; + + if (!xkb->map) { + mask= rep->present&XkbAllClientInfoMask; + if (mask&&(XkbAllocClientMap(xkb,mask,rep->nTypes)!=Success)) + return BadAlloc; + } + if (!xkb->server) { + mask= rep->present&XkbAllServerInfoMask; + if (mask&&(XkbAllocServerMap(xkb,mask,rep->totalActs)!=Success)) + return BadAlloc; + } + extraData= (int)(rep->length*4); + extraData-= (SIZEOF(xkbGetMapReply)-SIZEOF(xGenericReply)); + if (rep->length) { + XkbReadBufferRec buf; + int left; + if (_XkbInitReadBuffer(dpy,&buf,extraData)) { + Status status= Success; + if (nread_rtrn!=NULL) + *nread_rtrn= extraData; + if (status==Success) + status= _XkbReadKeyTypes(&buf,xkb,rep); + if (status==Success) + status= _XkbReadKeySyms(&buf,xkb,rep); + if (status==Success) + status= _XkbReadKeyActions(&buf,xkb,rep); + if (status==Success) + status= _XkbReadKeyBehaviors(&buf,xkb,rep); + if (status==Success) + status= _XkbReadVirtualMods(&buf,xkb,rep); + if (status==Success) + status= _XkbReadExplicitComponents(&buf,xkb,rep); + if (status==Success) + status= _XkbReadModifierMap(&buf,xkb,rep); + if (status==Success) + status= _XkbReadVirtualModMap(&buf,xkb,rep); + left= _XkbFreeReadBuffer(&buf); + if (status!=Success) return status; + else if ( left || buf.error ) return BadLength; + } + else return BadAlloc; + } + return Success; +} + +static Status +#if NeedFunctionPrototypes +_XkbHandleGetMapReply(Display *dpy,XkbDescPtr xkb) +#else +_XkbHandleGetMapReply(dpy,xkb) + Display * dpy; + XkbDescPtr xkb; +#endif +{ +xkbGetMapReply rep; + + if (!_XReply(dpy, (xReply *)&rep, + ( (SIZEOF(xkbGetMapReply)-SIZEOF(xGenericReply)) >> 2 ), + xFalse)) { + return BadImplementation; + } + return _XkbReadGetMapReply(dpy,&rep,xkb,NULL); +} + +Status +#if NeedFunctionPrototypes +XkbGetUpdatedMap(Display *dpy,unsigned which,XkbDescPtr xkb) +#else +XkbGetUpdatedMap(dpy,which,xkb) + Display * dpy; + unsigned which; + XkbDescPtr xkb; +#endif +{ + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) + return BadAccess; + if (which) { + register xkbGetMapReq *req; + Status status; + + LockDisplay(dpy); + + req = _XkbGetGetMapReq(dpy, xkb); + req->full = which; + status= _XkbHandleGetMapReply(dpy, xkb); + + UnlockDisplay(dpy); + SyncHandle(); + return status; + } + return Success; +} + +XkbDescPtr +#if NeedFunctionPrototypes +XkbGetMap(Display *dpy,unsigned which,unsigned deviceSpec) +#else +XkbGetMap(dpy,which,deviceSpec) + Display *dpy; + unsigned which; + unsigned deviceSpec; +#endif +{ +XkbDescPtr xkb; + + xkb = _XkbTypedCalloc(1,XkbDescRec); + if (xkb) { + xkb->device_spec = deviceSpec; + xkb->map = _XkbTypedCalloc(1,XkbClientMapRec); + if ((xkb->map==NULL)|| + ((which)&&(XkbGetUpdatedMap(dpy,which,xkb)!=Success))) { + if (xkb->map) { + Xfree(xkb->map); + xkb->map= NULL; + } + Xfree(xkb); + return NULL; + } + xkb->dpy= dpy; + } + return xkb; +} + +Status +#if NeedFunctionPrototypes +XkbGetKeyTypes(Display *dpy,unsigned first,unsigned num,XkbDescPtr xkb) +#else +XkbGetKeyTypes(dpy,first,num,xkb) + Display *dpy; + unsigned first; + unsigned num; + XkbDescPtr xkb; +#endif +{ + register xkbGetMapReq *req; + Status status; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) + return BadAccess; + if ((num<1)||(num>XkbMaxKeyTypes)) + return BadValue; + + LockDisplay(dpy); + + req = _XkbGetGetMapReq(dpy, xkb); + req->firstType = first; + req->nTypes = num; + status= _XkbHandleGetMapReply(dpy, xkb); + + UnlockDisplay(dpy); + SyncHandle(); + return status; +} + +Status +#if NeedFunctionPrototypes +XkbGetKeyActions(Display *dpy,unsigned first,unsigned num,XkbDescPtr xkb) +#else +XkbGetKeyActions(dpy,first,num,xkb) + Display *dpy; + unsigned first; + unsigned num; + XkbDescPtr xkb; +#endif +{ + register xkbGetMapReq *req; + Status status; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) + return BadAccess; + + if ((num<1)||(num>XkbMaxKeyCount)) + return BadValue; + + LockDisplay(dpy); + + req = _XkbGetGetMapReq(dpy, xkb); + req->firstKeyAct = first; + req->nKeyActs = num; + status= _XkbHandleGetMapReply(dpy, xkb); + + UnlockDisplay(dpy); + SyncHandle(); + return status; +} + +Status +#if NeedFunctionPrototypes +XkbGetKeySyms(Display *dpy,unsigned first,unsigned num,XkbDescPtr xkb) +#else +XkbGetKeySyms(dpy,first,num,xkb) + Display *dpy; + unsigned first; + unsigned num; + XkbDescPtr xkb; +#endif +{ + register xkbGetMapReq *req; + Status status; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) + return BadAccess; + + if ((num<1)||(num>XkbMaxKeyCount)) + return BadValue; + + LockDisplay(dpy); + + req = _XkbGetGetMapReq(dpy, xkb); + req->firstKeySym = first; + req->nKeySyms = num; + status= _XkbHandleGetMapReply(dpy, xkb); + + UnlockDisplay(dpy); + SyncHandle(); + + return status; +} + +Status +#if NeedFunctionPrototypes +XkbGetKeyBehaviors(Display *dpy,unsigned first,unsigned num,XkbDescPtr xkb) +#else +XkbGetKeyBehaviors(dpy,first,num,xkb) + Display * dpy; + unsigned first; + unsigned num; + XkbDescPtr xkb; +#endif +{ + register xkbGetMapReq *req; + Status status; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) + return BadAccess; + + if ((num<1)||(num>XkbMaxKeyCount)) + return BadValue; + + LockDisplay(dpy); + + req = _XkbGetGetMapReq(dpy, xkb); + req->firstKeyBehavior = first; + req->nKeyBehaviors = num; + status= _XkbHandleGetMapReply(dpy, xkb); + + UnlockDisplay(dpy); + SyncHandle(); + return status; +} + +Status +#if NeedFunctionPrototypes +XkbGetVirtualMods(Display *dpy,unsigned which,XkbDescPtr xkb) +#else +XkbGetVirtualMods(dpy,which,xkb) + Display * dpy; + unsigned which; + XkbDescPtr xkb; +#endif +{ + register xkbGetMapReq *req; + Status status; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) + return BadAccess; + + LockDisplay(dpy); + + req = _XkbGetGetMapReq(dpy, xkb); + req->virtualMods = which; + status= _XkbHandleGetMapReply(dpy, xkb); + + UnlockDisplay(dpy); + SyncHandle(); + return status; +} + +Status +#if NeedFunctionPrototypes +XkbGetKeyExplicitComponents( Display * dpy, + unsigned first, + unsigned num, + XkbDescPtr xkb) +#else +XkbGetKeyExplicitComponents(dpy,first,num,xkb) + Display *dpy; + unsigned first; + unsigned num; + XkbDescPtr xkb; +#endif +{ + register xkbGetMapReq *req; + Status status; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) + return BadAccess; + + if ((num<1)||(num>XkbMaxKeyCount)) + return BadValue; + + LockDisplay(dpy); + + req = _XkbGetGetMapReq(dpy, xkb); + req->firstKeyExplicit = first; + req->nKeyExplicit = num; + if ((xkb!=NULL) && (xkb->server!=NULL) && (xkb->server->explicit!=NULL)) { + if ((num>0)&&(first>=xkb->min_key_code)&&(first+num<=xkb->max_key_code)) + bzero(&xkb->server->explicit[first],num); + } + status= _XkbHandleGetMapReply(dpy, xkb); + + UnlockDisplay(dpy); + SyncHandle(); + return status; +} + +Status +#if NeedFunctionPrototypes +XkbGetKeyModifierMap(Display *dpy,unsigned first,unsigned num,XkbDescPtr xkb) +#else +XkbGetKeyModifierMap(dpy,first,num,xkb) + Display * dpy; + unsigned first; + unsigned num; + XkbDescPtr xkb; +#endif +{ + register xkbGetMapReq *req; + Status status; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) + return BadAccess; + + if ((num<1)||(num>XkbMaxKeyCount)) + return BadValue; + + LockDisplay(dpy); + + req = _XkbGetGetMapReq(dpy, xkb); + req->firstModMapKey = first; + req->nModMapKeys = num; + if ((xkb!=NULL) && (xkb->map!=NULL) && (xkb->map->modmap!=NULL)) { + if ((num>0)&&(first>=xkb->min_key_code)&&(first+num<=xkb->max_key_code)) + bzero(&xkb->map->modmap[first],num); + } + status= _XkbHandleGetMapReply(dpy, xkb); + + UnlockDisplay(dpy); + SyncHandle(); + return status; +} + +Status +#if NeedFunctionPrototypes +XkbGetKeyVirtualModMap(Display *dpy,unsigned first,unsigned num,XkbDescPtr xkb) +#else +XkbGetKeyVirtualModMap(dpy,first,num,xkb) + Display *dpy; + unsigned first; + unsigned num; + XkbDescPtr xkb; +#endif +{ + register xkbGetMapReq *req; + Status status; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) + return BadAccess; + + if ((num<1)||(num>XkbMaxKeyCount)) + return BadValue; + + LockDisplay(dpy); + + req = _XkbGetGetMapReq(dpy, xkb); + req->firstVModMapKey = first; + req->nVModMapKeys = num; + if ((xkb!=NULL) && (xkb->map!=NULL) && (xkb->map->modmap!=NULL)) { + if ((num>0)&&(first>=xkb->min_key_code)&&(first+num<=xkb->max_key_code)) + bzero(&xkb->server->vmodmap[first],num*sizeof(unsigned short)); + } + status= _XkbHandleGetMapReply(dpy, xkb); + + UnlockDisplay(dpy); + SyncHandle(); + return status; +} + +Status +#if NeedFunctionPrototypes +XkbGetMapChanges(Display *dpy,XkbDescPtr xkb,XkbMapChangesPtr changes) +#else +XkbGetMapChanges(dpy,xkb,changes) + Display * dpy; + XkbDescPtr xkb; + XkbMapChangesPtr changes; +#endif +{ + xkbGetMapReq *req; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) + return BadAccess; + LockDisplay(dpy); + if (changes->changed) { + Status status= Success; + req = _XkbGetGetMapReq(dpy, xkb); + req->full = 0; + req->partial = changes->changed; + req->firstType = changes->first_type; + req->nTypes = changes->num_types; + req->firstKeySym = changes->first_key_sym; + req->nKeySyms = changes->num_key_syms; + req->firstKeyAct = changes->first_key_act; + req->nKeyActs = changes->num_key_acts; + req->firstKeyBehavior = changes->first_key_behavior; + req->nKeyBehaviors = changes->num_key_behaviors; + req->virtualMods = changes->vmods; + req->firstKeyExplicit = changes->first_key_explicit; + req->nKeyExplicit = changes->num_key_explicit; + req->firstModMapKey = changes->first_modmap_key; + req->nModMapKeys = changes->num_modmap_keys; + req->firstVModMapKey = changes->first_vmodmap_key; + req->nVModMapKeys = changes->num_vmodmap_keys; + status= _XkbHandleGetMapReply(dpy, xkb); + SyncHandle(); + UnlockDisplay(dpy); + return status; + } + return Success; +} + diff --git a/src/xkb/XKBList.c b/src/xkb/XKBList.c new file mode 100644 index 00000000..9f521a60 --- /dev/null +++ b/src/xkb/XKBList.c @@ -0,0 +1,273 @@ +/* $Xorg: XKBList.c,v 1.3 2000/08/17 19:45:02 cpqbld Exp $ */ +/************************************************************ +Copyright (c) 1995 by Silicon Graphics Computer Systems, Inc. + +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 Silicon Graphics not be +used in advertising or publicity pertaining to distribution +of the software without specific prior written permission. +Silicon Graphics makes no representation about the suitability +of this software for any purpose. It is provided "as is" +without any express or implied warranty. + +SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS +SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON +GRAPHICS 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. + +********************************************************/ + +#define NEED_REPLIES +#define NEED_EVENTS +#define NEED_MAP_READERS +#include "Xlibint.h" +#include <X11/extensions/XKBproto.h> +#include "XKBlibint.h" + +/***====================================================================***/ + +static void +#if NeedFunctionPrototypes +_FreeComponentNames(int num,XkbComponentNamePtr names) +#else +_FreeComponentNames(num,names) + int num; + XkbComponentNamePtr names; +#endif +{ +int i; +XkbComponentNamePtr tmp; + + if ((num<1)||(names==NULL)) + return; + for (i=0,tmp=names;i<num;i++,tmp++) { + if (tmp->name) { + _XkbFree(tmp->name); + tmp->name= NULL; + } + } + _XkbFree(names); + return; +} + +/***====================================================================***/ + +static XkbComponentNamePtr +#if NeedFunctionPrototypes +_ReadListing(XkbReadBufferPtr buf,int count,Status *status_rtrn) +#else +_ReadListing(buf,count,status_rtrn) + XkbReadBufferPtr buf; + int count; + Status * status_rtrn; +#endif +{ +XkbComponentNamePtr first,this; +register int i; +CARD16 * flags; +int slen,wlen; +char * str; + + if (count<1) + return NULL; + first= _XkbTypedCalloc(count,XkbComponentNameRec); + if (!first) + return NULL; + for (this=first,i=0;i<count;i++,this++) { + flags= (CARD16 *)_XkbGetReadBufferPtr(buf,2*sizeof(CARD16)); + if (!flags) + goto BAILOUT; + this->flags= flags[0]; + slen= flags[1]; + wlen= ((slen+1)/2)*2; /* pad to 2 byte boundary */ + this->name= _XkbTypedCalloc(slen+1,char); + if (!this->name) + goto BAILOUT; + str= (char *)_XkbGetReadBufferPtr(buf,wlen); + memcpy(this->name,str,slen); + } + return first; +BAILOUT: + *status_rtrn= BadAlloc; + _FreeComponentNames(i,first); + return NULL; +} + +/***====================================================================***/ + +XkbComponentListPtr +#if NeedFunctionPrototypes +XkbListComponents( Display * dpy, + unsigned deviceSpec, + XkbComponentNamesPtr ptrns, + int * max_inout) +#else +XkbListComponents(dpy,deviceSpec,ptrns,max_inout) + Display * dpy; + unsigned deviceSpec; + XkbComponentNamesPtr ptrns; + int * max_inout; +#endif +{ +register xkbListComponentsReq* req; +xkbListComponentsReply rep; +XkbInfoPtr xkbi; +XkbComponentListPtr list; +XkbReadBufferRec buf; +int left; +char * str; +int extraLen,len,mapLen,codesLen,typesLen,compatLen,symsLen,geomLen; + + if ( (dpy==NULL) || (dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL)) || + (ptrns==NULL) || (max_inout==NULL)) + return NULL; + + xkbi= dpy->xkb_info; + LockDisplay(dpy); + GetReq(kbListComponents, req); + req->reqType = xkbi->codes->major_opcode; + req->xkbReqType = X_kbListComponents; + req->deviceSpec = deviceSpec; + req->maxNames = *max_inout; + + mapLen= codesLen= typesLen= compatLen= symsLen= geomLen= 0; + if (ptrns->keymap) + mapLen= (int)strlen(ptrns->keymap); + if (ptrns->keycodes) + codesLen= (int)strlen(ptrns->keycodes); + if (ptrns->types) + typesLen= (int)strlen(ptrns->types); + if (ptrns->compat) + compatLen= (int)strlen(ptrns->compat); + if (ptrns->symbols) + symsLen= (int)strlen(ptrns->symbols); + if (ptrns->geometry) + geomLen= (int)strlen(ptrns->geometry); + if (mapLen>255) mapLen= 255; + if (codesLen>255) codesLen= 255; + if (typesLen>255) typesLen= 255; + if (compatLen>255) compatLen= 255; + if (symsLen>255) symsLen= 255; + if (geomLen>255) geomLen= 255; + + len= mapLen+codesLen+typesLen+compatLen+symsLen+geomLen+6; + len= XkbPaddedSize(len); + req->length+= len/4; + BufAlloc(char *,str,len); + *str++= mapLen; + if (mapLen>0) { + memcpy(str,ptrns->keymap,mapLen); + str+= mapLen; + } + *str++= codesLen; + if (codesLen>0) { + memcpy(str,ptrns->keycodes,codesLen); + str+= codesLen; + } + *str++= typesLen; + if (typesLen>0) { + memcpy(str,ptrns->types,typesLen); + str+= typesLen; + } + *str++= compatLen; + if (compatLen>0) { + memcpy(str,ptrns->compat,compatLen); + str+= compatLen; + } + *str++= symsLen; + if (symsLen>0) { + memcpy(str,ptrns->symbols,symsLen); + str+= symsLen; + } + *str++= geomLen; + if (geomLen>0) { + memcpy(str,ptrns->geometry,geomLen); + str+= geomLen; + } + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) + goto BAILOUT; + extraLen= (int)rep.length*4; + *max_inout= rep.extra; + if (extraLen==0) { /* no matches, but we don't want to report a failure */ + list= _XkbTypedCalloc(1,XkbComponentListRec); + UnlockDisplay(dpy); + SyncHandle(); + return list; + } + if (_XkbInitReadBuffer(dpy,&buf,extraLen)) { + Status status; + + status= Success; + list= _XkbTypedCalloc(1,XkbComponentListRec); + if (!list) { + _XkbFreeReadBuffer(&buf); + goto BAILOUT; + } + list->num_keymaps= rep.nKeymaps; + list->num_keycodes= rep.nKeycodes; + list->num_types= rep.nTypes; + list->num_compat= rep.nCompatMaps; + list->num_symbols= rep.nSymbols; + list->num_geometry= rep.nGeometries; + if ((status==Success)&&(list->num_keymaps>0)) + list->keymaps= _ReadListing(&buf,list->num_keymaps,&status); + if ((status==Success)&&(list->num_keycodes>0)) + list->keycodes= _ReadListing(&buf,list->num_keycodes,&status); + if ((status==Success)&&(list->num_types>0)) + list->types= _ReadListing(&buf,list->num_types,&status); + if ((status==Success)&&(list->num_compat>0)) + list->compat= _ReadListing(&buf,list->num_compat,&status); + if ((status==Success)&&(list->num_symbols>0)) + list->symbols= _ReadListing(&buf,list->num_symbols,&status); + if ((status==Success)&&(list->num_geometry>0)) + list->geometry= _ReadListing(&buf,list->num_geometry,&status); + left= _XkbFreeReadBuffer(&buf); + if ((status!=Success)||(buf.error)||(left>2)) { + XkbFreeComponentList(list); + goto BAILOUT; + } + UnlockDisplay(dpy); + SyncHandle(); + return list; + } +BAILOUT: + UnlockDisplay(dpy); + SyncHandle(); + return NULL; +} + +void +#if NeedFunctionPrototypes +XkbFreeComponentList(XkbComponentListPtr list) +#else +XkbFreeComponentList(list) + XkbComponentListPtr list; +#endif +{ + if (list) { + if (list->keymaps) + _FreeComponentNames(list->num_keymaps,list->keymaps); + if (list->keycodes) + _FreeComponentNames(list->num_keycodes,list->keycodes); + if (list->types) + _FreeComponentNames(list->num_types,list->types); + if (list->compat) + _FreeComponentNames(list->num_compat,list->compat); + if (list->symbols) + _FreeComponentNames(list->num_symbols,list->symbols); + if (list->geometry) + _FreeComponentNames(list->num_geometry,list->geometry); + bzero((char *)list,sizeof(XkbComponentListRec)); + _XkbFree(list); + } + return; +} diff --git a/src/xkb/XKBMAlloc.c b/src/xkb/XKBMAlloc.c new file mode 100644 index 00000000..ba2a7076 --- /dev/null +++ b/src/xkb/XKBMAlloc.c @@ -0,0 +1,1077 @@ +/* $Xorg: XKBMAlloc.c,v 1.4 2000/08/17 19:45:02 cpqbld Exp $ */ +/************************************************************ +Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc. + +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 Silicon Graphics not be +used in advertising or publicity pertaining to distribution +of the software without specific prior written permission. +Silicon Graphics makes no representation about the suitability +of this software for any purpose. It is provided "as is" +without any express or implied warranty. + +SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS +SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON +GRAPHICS 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. + +********************************************************/ + +#ifndef XKB_IN_SERVER + +#include <stdio.h> +#define NEED_REPLIES +#define NEED_EVENTS +#include "Xlibint.h" +#include <X11/extensions/XKBproto.h> +#include <X11/keysym.h> +#include "XKBlibint.h" + +#else + +#include <stdio.h> +#include "X.h" +#define NEED_EVENTS +#define NEED_REPLIES +#include "Xproto.h" +#include "misc.h" +#include "inputstr.h" +#include <X11/keysym.h> +#define XKBSRV_NEED_FILE_FUNCS +#include "XKBsrv.h" + +#endif /* XKB_IN_SERVER */ + +/***====================================================================***/ + +Status +#if NeedFunctionPrototypes +XkbAllocClientMap(XkbDescPtr xkb,unsigned which,unsigned nTotalTypes) +#else +XkbAllocClientMap(xkb,which,nTotalTypes) + XkbDescPtr xkb; + unsigned which; + unsigned nTotalTypes; +#endif +{ +register int i; +XkbClientMapPtr map; + + if ((xkb==NULL)||((nTotalTypes>0)&&(nTotalTypes<XkbNumRequiredTypes))) + return BadValue; + if ((which&XkbKeySymsMask)&& + ((!XkbIsLegalKeycode(xkb->min_key_code))|| + (!XkbIsLegalKeycode(xkb->max_key_code))|| + (xkb->max_key_code<xkb->min_key_code))) { +#ifdef DEBUG +fprintf(stderr,"bad keycode (%d,%d) in XkbAllocClientMap\n", + xkb->min_key_code,xkb->max_key_code); +#endif + return BadValue; + } + + if (xkb->map==NULL) { + map= _XkbTypedCalloc(1,XkbClientMapRec); + if (map==NULL) + return BadAlloc; + xkb->map= map; + } + else map= xkb->map; + + if ((which&XkbKeyTypesMask)&&(nTotalTypes>0)) { + if (map->types==NULL) { + map->types= _XkbTypedCalloc(nTotalTypes,XkbKeyTypeRec); + if (map->types==NULL) + return BadAlloc; + map->num_types= 0; + map->size_types= nTotalTypes; + } + else if (map->size_types<nTotalTypes) { + XkbKeyTypeRec *prev_types = map->types; + + map->types= _XkbTypedRealloc(map->types,nTotalTypes,XkbKeyTypeRec); + if (map->types==NULL) { + _XkbFree(prev_types); + map->num_types= map->size_types= 0; + return BadAlloc; + } + map->size_types= nTotalTypes; + bzero(&map->types[map->num_types], + ((map->size_types-map->num_types)*sizeof(XkbKeyTypeRec))); + } + } + if (which&XkbKeySymsMask) { + int nKeys= XkbNumKeys(xkb); + if (map->syms==NULL) { + map->size_syms= (nKeys*15)/10; + map->syms= _XkbTypedCalloc(map->size_syms,KeySym); + if (!map->syms) { + map->size_syms= 0; + return BadAlloc; + } + map->num_syms= 1; + map->syms[0]= NoSymbol; + } + if (map->key_sym_map==NULL) { + i= xkb->max_key_code+1; + map->key_sym_map= _XkbTypedCalloc(i,XkbSymMapRec); + if (map->key_sym_map==NULL) + return BadAlloc; + } + } + if (which&XkbModifierMapMask) { + if ((!XkbIsLegalKeycode(xkb->min_key_code))|| + (!XkbIsLegalKeycode(xkb->max_key_code))|| + (xkb->max_key_code<xkb->min_key_code)) + return BadMatch; + if (map->modmap==NULL) { + i= xkb->max_key_code+1; + map->modmap= _XkbTypedCalloc(i,unsigned char); + if (map->modmap==NULL) + return BadAlloc; + } + } + return Success; +} + +Status +#if NeedFunctionPrototypes +XkbAllocServerMap(XkbDescPtr xkb,unsigned which,unsigned nNewActions) +#else +XkbAllocServerMap(xkb,which,nNewActions) + XkbDescPtr xkb; + unsigned which; + unsigned nNewActions; +#endif +{ +register int i; +XkbServerMapPtr map; + + if (xkb==NULL) + return BadMatch; + if (xkb->server==NULL) { + map= _XkbTypedCalloc(1,XkbServerMapRec); + if (map==NULL) + return BadAlloc; + for (i=0;i<XkbNumVirtualMods;i++) { + map->vmods[i]= XkbNoModifierMask; + } + xkb->server= map; + } + else map= xkb->server; + if (which&XkbExplicitComponentsMask) { + if ((!XkbIsLegalKeycode(xkb->min_key_code))|| + (!XkbIsLegalKeycode(xkb->max_key_code))|| + (xkb->max_key_code<xkb->min_key_code)) + return BadMatch; + if (map->explicit==NULL) { + i= xkb->max_key_code+1; + map->explicit= _XkbTypedCalloc(i,unsigned char); + if (map->explicit==NULL) + return BadAlloc; + } + } + if (which&XkbKeyActionsMask) { + if ((!XkbIsLegalKeycode(xkb->min_key_code))|| + (!XkbIsLegalKeycode(xkb->max_key_code))|| + (xkb->max_key_code<xkb->min_key_code)) + return BadMatch; + if (nNewActions<1) + nNewActions= 1; + if (map->acts==NULL) { + map->acts= _XkbTypedCalloc((nNewActions+1),XkbAction); + if (map->acts==NULL) + return BadAlloc; + map->num_acts= 1; + map->size_acts= nNewActions+1; + } + else if ((map->size_acts-map->num_acts)<nNewActions) { + unsigned need; + XkbAction *prev_acts = map->acts; + need= map->num_acts+nNewActions; + map->acts= _XkbTypedRealloc(map->acts,need,XkbAction); + if (map->acts==NULL) { + _XkbFree(prev_acts); + map->num_acts= map->size_acts= 0; + return BadAlloc; + } + map->size_acts= need; + bzero(&map->acts[map->num_acts], + ((map->size_acts-map->num_acts)*sizeof(XkbAction))); + } + if (map->key_acts==NULL) { + i= xkb->max_key_code+1; + map->key_acts= _XkbTypedCalloc(i,unsigned short); + if (map->key_acts==NULL) + return BadAlloc; + } + } + if (which&XkbKeyBehaviorsMask) { + if ((!XkbIsLegalKeycode(xkb->min_key_code))|| + (!XkbIsLegalKeycode(xkb->max_key_code))|| + (xkb->max_key_code<xkb->min_key_code)) + return BadMatch; + if (map->behaviors==NULL) { + i= xkb->max_key_code+1; + map->behaviors= _XkbTypedCalloc(i,XkbBehavior); + if (map->behaviors==NULL) + return BadAlloc; + } + } + if (which&XkbVirtualModMapMask) { + if ((!XkbIsLegalKeycode(xkb->min_key_code))|| + (!XkbIsLegalKeycode(xkb->max_key_code))|| + (xkb->max_key_code<xkb->min_key_code)) + return BadMatch; + if (map->vmodmap==NULL) { + i= xkb->max_key_code+1; + map->vmodmap= _XkbTypedCalloc(i,unsigned short); + if (map->vmodmap==NULL) + return BadAlloc; + } + } + return Success; +} + +/***====================================================================***/ + +Status +#if NeedFunctionPrototypes +XkbCopyKeyType(XkbKeyTypePtr from,XkbKeyTypePtr into) +#else +XkbCopyKeyType(from,into) + XkbKeyTypePtr from; + XkbKeyTypePtr into; +#endif +{ + if ((!from)||(!into)) + return BadMatch; + if (into->map) { + _XkbFree(into->map); + into->map= NULL; + } + if (into->preserve) { + _XkbFree(into->preserve); + into->preserve= NULL; + } + if (into->level_names) { + _XkbFree(into->level_names); + into->level_names= NULL; + } + *into= *from; + if ((from->map)&&(into->map_count>0)) { + into->map= _XkbTypedCalloc(into->map_count,XkbKTMapEntryRec); + if (!into->map) + return BadAlloc; + memcpy(into->map,from->map,into->map_count*sizeof(XkbKTMapEntryRec)); + } + if ((from->preserve)&&(into->map_count>0)) { + into->preserve= _XkbTypedCalloc(into->map_count,XkbModsRec); + if (!into->preserve) + return BadAlloc; + memcpy(into->preserve,from->preserve, + into->map_count*sizeof(XkbModsRec)); + } + if ((from->level_names)&&(into->num_levels>0)) { + into->level_names= _XkbTypedCalloc(into->num_levels,Atom); + if (!into->level_names) + return BadAlloc; + memcpy(into->level_names,from->level_names, + into->num_levels*sizeof(Atom)); + } + return Success; +} + +Status +#if NeedFunctionPrototypes +XkbCopyKeyTypes(XkbKeyTypePtr from,XkbKeyTypePtr into,int num_types) +#else +XkbCopyKeyTypes(from,into,num_types) + XkbKeyTypePtr from; + XkbKeyTypePtr into; + int num_types; +#endif +{ +register int i,rtrn; + + if ((!from)||(!into)||(num_types<0)) + return BadMatch; + for (i=0;i<num_types;i++) { + if ((rtrn= XkbCopyKeyType(from++,into++))!=Success) + return rtrn; + } + return Success; +} + +XkbKeyTypePtr +#if NeedFunctionPrototypes +XkbAddKeyType( XkbDescPtr xkb, + Atom name, + int map_count, + Bool want_preserve, + int num_lvls) +#else +XkbAddKeyType(xkb,name,map_count,want_preserve,num_lvls) + XkbDescPtr xkb; + Atom name; + int map_count; + Bool want_preserve; + int num_lvls; +#endif +{ +register int i; +unsigned tmp; +XkbKeyTypePtr type; +XkbClientMapPtr map; + + if ((!xkb)||(num_lvls<1)) + return NULL; + map= xkb->map; + if ((map)&&(map->types)) { + for (i=0;i<map->num_types;i++) { + if (map->types[i].name==name) { + Status status; + status=XkbResizeKeyType(xkb,i,map_count,want_preserve,num_lvls); + return (status==Success?&map->types[i]:NULL); + } + } + } + if ((!map)||(!map->types)||(!map->num_types<XkbNumRequiredTypes)) { + tmp= XkbNumRequiredTypes+1; + if (XkbAllocClientMap(xkb,XkbKeyTypesMask,tmp)!=Success) + return NULL; + tmp= 0; + if (map->num_types<=XkbKeypadIndex) + tmp|= XkbKeypadMask; + if (map->num_types<=XkbAlphabeticIndex) + tmp|= XkbAlphabeticMask; + if (map->num_types<=XkbTwoLevelIndex) + tmp|= XkbTwoLevelMask; + if (map->num_types<=XkbOneLevelIndex) + tmp|= XkbOneLevelMask; + if (XkbInitCanonicalKeyTypes(xkb,tmp,XkbNoModifier)==Success) { + for (i=0;i<map->num_types;i++) { + Status status; + if (map->types[i].name!=name) + continue; + status=XkbResizeKeyType(xkb,i,map_count,want_preserve,num_lvls); + return (status==Success?&map->types[i]:NULL); + } + } + } + if ((map->num_types<=map->size_types)&& + (XkbAllocClientMap(xkb,XkbKeyTypesMask,map->num_types+1)!=Success)) { + return NULL; + } + type= &map->types[map->num_types]; + map->num_types++; + bzero((char *)type,sizeof(XkbKeyTypeRec)); + type->num_levels= num_lvls; + type->map_count= map_count; + type->name= name; + if (map_count>0) { + type->map= _XkbTypedCalloc(map_count,XkbKTMapEntryRec); + if (!type->map) { + map->num_types--; + return NULL; + } + if (want_preserve) { + type->preserve= _XkbTypedCalloc(map_count,XkbModsRec); + if (!type->preserve) { + _XkbFree(type->map); + map->num_types--; + return NULL; + } + } + } + return type; +} + +Status +#if NeedFunctionPrototypes +XkbResizeKeyType( XkbDescPtr xkb, + int type_ndx, + int map_count, + Bool want_preserve, + int new_num_lvls) +#else +XkbResizeKeyType(xkb,type_ndx,map_count,want_preserve,new_num_lvls) + XkbDescPtr xkb; + int type_ndx; + int map_count; + Bool want_preserve; + int new_num_lvls; +#endif +{ +XkbKeyTypePtr type; +KeyCode matchingKeys[XkbMaxKeyCount],nMatchingKeys; + + if ((type_ndx<0)||(type_ndx>=xkb->map->num_types)||(map_count<0)|| + (new_num_lvls<1)) + return BadValue; + switch (type_ndx) { + case XkbOneLevelIndex: + if (new_num_lvls!=1) + return BadMatch; + break; + case XkbTwoLevelIndex: + case XkbAlphabeticIndex: + case XkbKeypadIndex: + if (new_num_lvls!=2) + return BadMatch; + break; + } + type= &xkb->map->types[type_ndx]; + if (map_count==0) { + if (type->map!=NULL) + _XkbFree(type->map); + type->map= NULL; + if (type->preserve!=NULL) + _XkbFree(type->preserve); + type->preserve= NULL; + type->map_count= 0; + } + else { + XkbKTMapEntryRec *prev_map = type->map; + + if ((map_count>type->map_count)||(type->map==NULL)) + type->map=_XkbTypedRealloc(type->map,map_count,XkbKTMapEntryRec); + if (!type->map) { + if (prev_map) + _XkbFree(prev_map); + return BadAlloc; + } + if (want_preserve) { + XkbModsRec *prev_preserve = type->preserve; + + if ((map_count>type->map_count)||(type->preserve==NULL)) { + type->preserve= _XkbTypedRealloc(type->preserve,map_count, + XkbModsRec); + } + if (!type->preserve) { + if (prev_preserve) + _XkbFree(prev_preserve); + return BadAlloc; + } + } + else if (type->preserve!=NULL) { + _XkbFree(type->preserve); + type->preserve= NULL; + } + type->map_count= map_count; + } + + if ((new_num_lvls>type->num_levels)||(type->level_names==NULL)) { + Atom * prev_level_names = type->level_names; + + type->level_names=_XkbTypedRealloc(type->level_names,new_num_lvls,Atom); + if (!type->level_names) { + if (prev_level_names) + _XkbFree(prev_level_names); + return BadAlloc; + } + } + /* + * Here's the theory: + * If the width of the type changed, we might have to resize the symbol + * maps for any keys that use the type for one or more groups. This is + * expensive, so we'll try to cull out any keys that are obviously okay: + * In any case: + * - keys that have a group width <= the old width are okay (because + * they could not possibly have been associated with the old type) + * If the key type increased in size: + * - keys that already have a group width >= to the new width are okay + * + keys that have a group width >= the old width but < the new width + * might have to be enlarged. + * If the key type decreased in size: + * - keys that have a group width > the old width don't have to be + * resized (because they must have some other wider type associated + * with some group). + * + keys that have a group width == the old width might have to be + * shrunk. + * The possibilities marked with '+' require us to examine the key types + * associated with each group for the key. + */ + bzero(matchingKeys,XkbMaxKeyCount*sizeof(KeyCode)); + nMatchingKeys= 0; + if (new_num_lvls>type->num_levels) { + int nTotal; + KeySym * newSyms; + int width,match,nResize; + register int i,g,nSyms; + + nResize= 0; + for (nTotal=1,i=xkb->min_key_code;i<=xkb->max_key_code;i++) { + width= XkbKeyGroupsWidth(xkb,i); + if (width<type->num_levels) + continue; + for (match=0,g=XkbKeyNumGroups(xkb,i)-1;(g>=0)&&(!match);g--) { + if (XkbKeyKeyTypeIndex(xkb,i,g)==type_ndx) { + matchingKeys[nMatchingKeys++]= i; + match= 1; + } + } + if ((!match)||(width>=new_num_lvls)) + nTotal+= XkbKeyNumSyms(xkb,i); + else { + nTotal+= XkbKeyNumGroups(xkb,i)*new_num_lvls; + nResize++; + } + } + if (nResize>0) { + int nextMatch; + xkb->map->size_syms= (nTotal*12)/10; + newSyms = _XkbTypedCalloc(xkb->map->size_syms,KeySym); + if (newSyms==NULL) + return BadAlloc; + nextMatch= 0; + nSyms= 1; + for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) { + if (matchingKeys[nextMatch]==i) { + KeySym *pOld; + nextMatch++; + width= XkbKeyGroupsWidth(xkb,i); + pOld= XkbKeySymsPtr(xkb,i); + for (g=XkbKeyNumGroups(xkb,i)-1;g>=0;g--) { + memcpy(&newSyms[nSyms+(new_num_lvls*g)],&pOld[width*g], + width*sizeof(KeySym)); + } + xkb->map->key_sym_map[i].offset= nSyms; + nSyms+= XkbKeyNumGroups(xkb,i)*new_num_lvls; + } + else { + memcpy(&newSyms[nSyms],XkbKeySymsPtr(xkb,i), + XkbKeyNumSyms(xkb,i)*sizeof(KeySym)); + xkb->map->key_sym_map[i].offset= nSyms; + nSyms+= XkbKeyNumSyms(xkb,i); + } + } + type->num_levels= new_num_lvls; + _XkbFree(xkb->map->syms); + xkb->map->syms= newSyms; + xkb->map->num_syms= nSyms; + return Success; + } + } + else if (new_num_lvls<type->num_levels) { + int width,match; + register int g,i; + for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) { + width= XkbKeyGroupsWidth(xkb,i); + if (width<type->num_levels) + continue; + for (match=0,g=XkbKeyNumGroups(xkb,i)-1;(g>=0)&&(!match);g--) { + if (XkbKeyKeyTypeIndex(xkb,i,g)==type_ndx) { + matchingKeys[nMatchingKeys++]= i; + match= 1; + } + } + } + } + if (nMatchingKeys>0) { + int key,firstClear; + register int i,g; + if (new_num_lvls>type->num_levels) + firstClear= type->num_levels; + else firstClear= new_num_lvls; + for (i=0;i<nMatchingKeys;i++) { + KeySym * pSyms; + int width,nClear; + + key= matchingKeys[i]; + width= XkbKeyGroupsWidth(xkb,key); + nClear= width-firstClear; + pSyms= XkbKeySymsPtr(xkb,key); + for (g=XkbKeyNumGroups(xkb,key)-1;g>=0;g--) { + if (XkbKeyKeyTypeIndex(xkb,key,g)==type_ndx) { + if (nClear>0) + bzero(&pSyms[g*width+firstClear],nClear*sizeof(KeySym)); + } + } + } + } + type->num_levels= new_num_lvls; + return Success; +} + +KeySym * +#if NeedFunctionPrototypes +XkbResizeKeySyms(XkbDescPtr xkb,int key,int needed) +#else +XkbResizeKeySyms(xkb,key,needed) + XkbDescPtr xkb; + int key; + int needed; +#endif +{ +register int i,nSyms,nKeySyms; +unsigned nOldSyms; +KeySym *newSyms; + + if (needed==0) { + xkb->map->key_sym_map[key].offset= 0; + return xkb->map->syms; + } + nOldSyms= XkbKeyNumSyms(xkb,key); + if (nOldSyms>=(unsigned)needed) { + return XkbKeySymsPtr(xkb,key); + } + if (xkb->map->size_syms-xkb->map->num_syms>=(unsigned)needed) { + if (nOldSyms>0) { + memcpy(&xkb->map->syms[xkb->map->num_syms],XkbKeySymsPtr(xkb,key), + nOldSyms*sizeof(KeySym)); + } + if ((needed-nOldSyms)>0) { + bzero(&xkb->map->syms[xkb->map->num_syms+XkbKeyNumSyms(xkb,key)], + (needed-nOldSyms)*sizeof(KeySym)); + } + xkb->map->key_sym_map[key].offset = xkb->map->num_syms; + xkb->map->num_syms+= needed; + return &xkb->map->syms[xkb->map->key_sym_map[key].offset]; + } + xkb->map->size_syms+= (needed>32?needed:32); + newSyms = _XkbTypedCalloc(xkb->map->size_syms,KeySym); + if (newSyms==NULL) + return NULL; + newSyms[0]= NoSymbol; + nSyms = 1; + for (i=xkb->min_key_code;i<=(int)xkb->max_key_code;i++) { + int nCopy; + + nCopy= nKeySyms= XkbKeyNumSyms(xkb,i); + if ((nKeySyms==0)&&(i!=key)) + continue; + if (i==key) + nKeySyms= needed; + if (nCopy!=0) + memcpy(&newSyms[nSyms],XkbKeySymsPtr(xkb,i),nCopy*sizeof(KeySym)); + if (nKeySyms>nCopy) + bzero(&newSyms[nSyms+nCopy],(nKeySyms-nCopy)*sizeof(KeySym)); + xkb->map->key_sym_map[i].offset = nSyms; + nSyms+= nKeySyms; + } + _XkbFree(xkb->map->syms); + xkb->map->syms = newSyms; + xkb->map->num_syms = nSyms; + return &xkb->map->syms[xkb->map->key_sym_map[key].offset]; +} + +static unsigned +#if NeedFunctionPrototypes +_ExtendRange( unsigned int old_flags, + unsigned int flag, + KeyCode newKC, + KeyCode * old_min, + unsigned char * old_num) +#else +_ExtendRange(old_flags,flag,newKC,old_min,old_num) + unsigned int old_flags; + unsigned int flag; + KeyCode newKC; + KeyCode * old_min; + unsigned char * old_num; +#endif +{ + if ((old_flags&flag)==0) { + old_flags|= flag; + *old_min= newKC; + *old_num= 1; + } + else { + int last= (*old_min)+(*old_num)-1; + if (newKC<*old_min) { + *old_min= newKC; + *old_num= (last-newKC)+1; + } + else if (newKC>last) { + *old_num= (newKC-(*old_min))+1; + } + } + return old_flags; +} + +Status +#if NeedFunctionPrototypes +XkbChangeKeycodeRange( XkbDescPtr xkb, + int minKC, + int maxKC, + XkbChangesPtr changes) +#else +XkbChangeKeycodeRange(xkb,minKC,maxKC,changes) + XkbDescPtr xkb; + int minKC; + int maxKC; + XkbChangesPtr changes; +#endif +{ +int tmp; + + if ((!xkb)||(minKC<XkbMinLegalKeyCode)||(maxKC>XkbMaxLegalKeyCode)) + return BadValue; + if (minKC>maxKC) + return BadMatch; + if (minKC<xkb->min_key_code) { + if (changes) + changes->map.min_key_code= minKC; + tmp= xkb->min_key_code-minKC; + if (xkb->map) { + if (xkb->map->key_sym_map) { + bzero((char *)&xkb->map->key_sym_map[minKC], + tmp*sizeof(XkbSymMapRec)); + if (changes) { + changes->map.changed= _ExtendRange(changes->map.changed, + XkbKeySymsMask,minKC, + &changes->map.first_key_sym, + &changes->map.num_key_syms); + } + } + if (xkb->map->modmap) { + bzero((char *)&xkb->map->modmap[minKC],tmp); + if (changes) { + changes->map.changed= _ExtendRange(changes->map.changed, + XkbModifierMapMask,minKC, + &changes->map.first_modmap_key, + &changes->map.num_modmap_keys); + } + } + } + if (xkb->server) { + if (xkb->server->behaviors) { + bzero((char *)&xkb->server->behaviors[minKC], + tmp*sizeof(XkbBehavior)); + if (changes) { + changes->map.changed= _ExtendRange(changes->map.changed, + XkbKeyBehaviorsMask,minKC, + &changes->map.first_key_behavior, + &changes->map.num_key_behaviors); + } + } + if (xkb->server->key_acts) { + bzero((char *)&xkb->server->key_acts[minKC], + tmp*sizeof(unsigned short)); + if (changes) { + changes->map.changed= _ExtendRange(changes->map.changed, + XkbKeyActionsMask,minKC, + &changes->map.first_key_act, + &changes->map.num_key_acts); + } + } + if (xkb->server->vmodmap) { + bzero((char *)&xkb->server->vmodmap[minKC], + tmp*sizeof(unsigned short)); + if (changes) { + changes->map.changed= _ExtendRange(changes->map.changed, + XkbVirtualModMapMask,minKC, + &changes->map.first_modmap_key, + &changes->map.num_vmodmap_keys); + } + } + } + if ((xkb->names)&&(xkb->names->keys)) { + bzero((char *)&xkb->names->keys[minKC],tmp*sizeof(XkbKeyNameRec)); + if (changes) { + changes->names.changed= _ExtendRange(changes->names.changed, + XkbKeyNamesMask,minKC, + &changes->names.first_key, + &changes->names.num_keys); + } + } + xkb->min_key_code= minKC; + } + if (maxKC>xkb->max_key_code) { + if (changes) + changes->map.max_key_code= maxKC; + tmp= maxKC-xkb->max_key_code; + if (xkb->map) { + if (xkb->map->key_sym_map) { + XkbSymMapRec *prev_key_sym_map = xkb->map->key_sym_map; + + xkb->map->key_sym_map= _XkbTypedRealloc(xkb->map->key_sym_map, + (maxKC+1),XkbSymMapRec); + if (!xkb->map->key_sym_map) { + _XkbFree(prev_key_sym_map); + return BadAlloc; + } + bzero((char *)&xkb->map->key_sym_map[xkb->max_key_code], + tmp*sizeof(XkbSymMapRec)); + if (changes) { + changes->map.changed= _ExtendRange(changes->map.changed, + XkbKeySymsMask,maxKC, + &changes->map.first_key_sym, + &changes->map.num_key_syms); + } + } + if (xkb->map->modmap) { + unsigned char *prev_modmap = xkb->map->modmap; + + xkb->map->modmap= _XkbTypedRealloc(xkb->map->modmap, + (maxKC+1),unsigned char); + if (!xkb->map->modmap) { + _XkbFree(prev_modmap); + return BadAlloc; + } + bzero((char *)&xkb->map->modmap[xkb->max_key_code],tmp); + if (changes) { + changes->map.changed= _ExtendRange(changes->map.changed, + XkbModifierMapMask,maxKC, + &changes->map.first_modmap_key, + &changes->map.num_modmap_keys); + } + } + } + if (xkb->server) { + if (xkb->server->behaviors) { + XkbBehavior *prev_behaviors = xkb->server->behaviors; + + xkb->server->behaviors=_XkbTypedRealloc(xkb->server->behaviors, + (maxKC+1),XkbBehavior); + if (!xkb->server->behaviors) { + _XkbFree(prev_behaviors); + return BadAlloc; + } + bzero((char *)&xkb->server->behaviors[xkb->max_key_code], + tmp*sizeof(XkbBehavior)); + if (changes) { + changes->map.changed= _ExtendRange(changes->map.changed, + XkbKeyBehaviorsMask,maxKC, + &changes->map.first_key_behavior, + &changes->map.num_key_behaviors); + } + } + if (xkb->server->key_acts) { + unsigned short *prev_key_acts = xkb->server->key_acts; + + xkb->server->key_acts= _XkbTypedRealloc(xkb->server->key_acts, + (maxKC+1),unsigned short); + if (!xkb->server->key_acts) { + _XkbFree(prev_key_acts); + return BadAlloc; + } + bzero((char *)&xkb->server->key_acts[xkb->max_key_code], + tmp*sizeof(unsigned short)); + if (changes) { + changes->map.changed= _ExtendRange(changes->map.changed, + XkbKeyActionsMask,maxKC, + &changes->map.first_key_act, + &changes->map.num_key_acts); + } + } + if (xkb->server->vmodmap) { + unsigned short *prev_vmodmap = xkb->server->vmodmap; + + xkb->server->vmodmap= _XkbTypedRealloc(xkb->server->vmodmap, + (maxKC+1),unsigned short); + if (!xkb->server->vmodmap) { + _XkbFree(prev_vmodmap); + return BadAlloc; + } + bzero((char *)&xkb->server->vmodmap[xkb->max_key_code], + tmp*sizeof(unsigned short)); + if (changes) { + changes->map.changed= _ExtendRange(changes->map.changed, + XkbVirtualModMapMask,maxKC, + &changes->map.first_modmap_key, + &changes->map.num_vmodmap_keys); + } + } + } + if ((xkb->names)&&(xkb->names->keys)) { + XkbKeyNameRec *prev_keys = xkb->names->keys; + + xkb->names->keys= _XkbTypedRealloc(xkb->names->keys, + (maxKC+1),XkbKeyNameRec); + if (!xkb->names->keys) { + _XkbFree(prev_keys); + return BadAlloc; + } + bzero((char *)&xkb->names->keys[xkb->max_key_code], + tmp*sizeof(XkbKeyNameRec)); + if (changes) { + changes->names.changed= _ExtendRange(changes->names.changed, + XkbKeyNamesMask,maxKC, + &changes->names.first_key, + &changes->names.num_keys); + } + } + xkb->max_key_code= maxKC; + } + return Success; +} + +XkbAction * +#if NeedFunctionPrototypes +XkbResizeKeyActions(XkbDescPtr xkb,int key,int needed) +#else +XkbResizeKeyActions(xkb,key,needed) + XkbDescPtr xkb; + int key; + int needed; +#endif +{ +register int i,nActs; +XkbAction *newActs; + + if (needed==0) { + xkb->server->key_acts[key]= 0; + return NULL; + } + if (XkbKeyHasActions(xkb,key)&&(XkbKeyNumSyms(xkb,key)>=(unsigned)needed)) + return XkbKeyActionsPtr(xkb,key); + if (xkb->server->size_acts-xkb->server->num_acts>=(unsigned)needed) { + xkb->server->key_acts[key]= xkb->server->num_acts; + xkb->server->num_acts+= needed; + return &xkb->server->acts[xkb->server->key_acts[key]]; + } + xkb->server->size_acts= xkb->server->num_acts+needed+8; + newActs = _XkbTypedCalloc(xkb->server->size_acts,XkbAction); + if (newActs==NULL) + return NULL; + newActs[0].type = XkbSA_NoAction; + nActs = 1; + for (i=xkb->min_key_code;i<=(int)xkb->max_key_code;i++) { + int nKeyActs,nCopy; + + if ((xkb->server->key_acts[i]==0)&&(i!=key)) + continue; + + nCopy= nKeyActs= XkbKeyNumActions(xkb,i); + if (i==key) { + nKeyActs= needed; + if (needed<nCopy) + nCopy= needed; + } + + if (nCopy>0) + memcpy(&newActs[nActs],XkbKeyActionsPtr(xkb,i), + nCopy*sizeof(XkbAction)); + if (nCopy<nKeyActs) + bzero(&newActs[nActs+nCopy],(nKeyActs-nCopy)*sizeof(XkbAction)); + xkb->server->key_acts[i]= nActs; + nActs+= nKeyActs; + } + _XkbFree(xkb->server->acts); + xkb->server->acts = newActs; + xkb->server->num_acts= nActs; + return &xkb->server->acts[xkb->server->key_acts[key]]; +} + +void +#if NeedFunctionPrototypes +XkbFreeClientMap(XkbDescPtr xkb,unsigned what,Bool freeMap) +#else +XkbFreeClientMap(xkb,what,freeMap) + XkbDescPtr xkb; + unsigned what; + Bool freeMap; +#endif +{ +XkbClientMapPtr map; + + if ((xkb==NULL)||(xkb->map==NULL)) + return; + if (freeMap) + what= XkbAllClientInfoMask; + map= xkb->map; + if (what&XkbKeyTypesMask) { + if (map->types!=NULL) { + if (map->num_types>0) { + register int i; + XkbKeyTypePtr type; + for (i=0,type=map->types;i<map->num_types;i++,type++) { + if (type->map!=NULL) { + _XkbFree(type->map); + type->map= NULL; + } + if (type->preserve!=NULL) { + _XkbFree(type->preserve); + type->preserve= NULL; + } + type->map_count= 0; + if (type->level_names!=NULL) { + _XkbFree(type->level_names); + type->level_names= NULL; + } + } + } + _XkbFree(map->types); + map->num_types= map->size_types= 0; + map->types= NULL; + } + } + if (what&XkbKeySymsMask) { + if (map->key_sym_map!=NULL) { + _XkbFree(map->key_sym_map); + map->key_sym_map= NULL; + } + if (map->syms!=NULL) { + _XkbFree(map->syms); + map->size_syms= map->num_syms= 0; + map->syms= NULL; + } + } + if ((what&XkbModifierMapMask)&&(map->modmap!=NULL)) { + _XkbFree(map->modmap); + map->modmap= NULL; + } + if (freeMap) { + _XkbFree(xkb->map); + xkb->map= NULL; + } + return; +} + +void +#if NeedFunctionPrototypes +XkbFreeServerMap(XkbDescPtr xkb,unsigned what,Bool freeMap) +#else +XkbFreeServerMap(xkb,what,freeMap) + XkbDescPtr xkb; + unsigned what; + Bool freeMap; +#endif +{ +XkbServerMapPtr map; + + if ((xkb==NULL)||(xkb->server==NULL)) + return; + if (freeMap) + what= XkbAllServerInfoMask; + map= xkb->server; + if ((what&XkbExplicitComponentsMask)&&(map->explicit!=NULL)) { + _XkbFree(map->explicit); + map->explicit= NULL; + } + if (what&XkbKeyActionsMask) { + if (map->key_acts!=NULL) { + _XkbFree(map->key_acts); + map->key_acts= NULL; + } + if (map->acts!=NULL) { + _XkbFree(map->acts); + map->num_acts= map->size_acts= 0; + map->acts= NULL; + } + } + if ((what&XkbKeyBehaviorsMask)&&(map->behaviors!=NULL)) { + _XkbFree(map->behaviors); + map->behaviors= NULL; + } + if ((what&XkbVirtualModMapMask)&&(map->vmodmap!=NULL)) { + _XkbFree(map->vmodmap); + map->vmodmap= NULL; + } + + if (freeMap) { + _XkbFree(xkb->server); + xkb->server= NULL; + } + return; +} diff --git a/src/xkb/XKBMisc.c b/src/xkb/XKBMisc.c new file mode 100644 index 00000000..45c00692 --- /dev/null +++ b/src/xkb/XKBMisc.c @@ -0,0 +1,1071 @@ +/* $Xorg: XKBMisc.c,v 1.4 2000/08/17 19:45:02 cpqbld Exp $ */ +/************************************************************ +Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc. + +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 Silicon Graphics not be +used in advertising or publicity pertaining to distribution +of the software without specific prior written permission. +Silicon Graphics makes no representation about the suitability +of this software for any purpose. It is provided "as is" +without any express or implied warranty. + +SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS +SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON +GRAPHICS 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. + +********************************************************/ + +#ifndef XKB_IN_SERVER + +#include <stdio.h> +#define NEED_REPLIES +#define NEED_EVENTS +#include "Xlibint.h" +#include <X11/extensions/XKBproto.h> +#include <X11/keysym.h> +#include "XKBlibint.h" + +#else + +#include <stdio.h> +#include "X.h" +#define NEED_EVENTS +#define NEED_REPLIES +#include "Xproto.h" +#include "misc.h" +#include "inputstr.h" +#include <X11/keysym.h> +#define XKBSRV_NEED_FILE_FUNCS +#include "XKBsrv.h" + +#endif /* XKB_IN_SERVER */ + +/***====================================================================***/ + +#define mapSize(m) (sizeof(m)/sizeof(XkbKTMapEntryRec)) +static XkbKTMapEntryRec map2Level[]= { + { True, ShiftMask, 1, ShiftMask, 0 } +}; + +static XkbKTMapEntryRec mapAlpha[]= { + { True, ShiftMask, 1, ShiftMask, 0 }, + { True, LockMask, 0, LockMask, 0 } +}; + +static XkbModsRec preAlpha[]= { + { 0, 0, 0 }, + { LockMask, LockMask, 0 } +}; + +#define NL_VMOD_MASK 0 +static XkbKTMapEntryRec mapKeypad[]= { + { True, ShiftMask, 1, ShiftMask, 0 }, + { False, 0, 1, 0, NL_VMOD_MASK } +}; + +static XkbKeyTypeRec canonicalTypes[XkbNumRequiredTypes] = { + { { 0, 0, 0 }, + 1, /* num_levels */ + 0, /* map_count */ + NULL, NULL, + None, NULL + }, + { { ShiftMask, ShiftMask, 0 }, + 2, /* num_levels */ + mapSize(map2Level), /* map_count */ + map2Level, NULL, + None, NULL + }, + { { ShiftMask|LockMask, ShiftMask|LockMask, 0 }, + 2, /* num_levels */ + mapSize(mapAlpha), /* map_count */ + mapAlpha, preAlpha, + None, NULL + }, + { { ShiftMask, ShiftMask, NL_VMOD_MASK }, + 2, /* num_levels */ + mapSize(mapKeypad), /* map_count */ + mapKeypad, NULL, + None, NULL + } +}; + +Status +#if NeedFunctionPrototypes +XkbInitCanonicalKeyTypes(XkbDescPtr xkb,unsigned which,int keypadVMod) +#else +XkbInitCanonicalKeyTypes(xkb,which,keypadVMod) + XkbDescPtr xkb; + unsigned which; + int keypadVMod; +#endif +{ +XkbClientMapPtr map; +XkbKeyTypePtr from,to; +Status rtrn; + + if (!xkb) + return BadMatch; + rtrn= XkbAllocClientMap(xkb,XkbKeyTypesMask,XkbNumRequiredTypes); + if (rtrn!=Success) + return rtrn; + map= xkb->map; + if ((which&XkbAllRequiredTypes)==0) + return Success; + rtrn= Success; + from= canonicalTypes; + to= map->types; + if (which&XkbOneLevelMask) + rtrn= XkbCopyKeyType(&from[XkbOneLevelIndex],&to[XkbOneLevelIndex]); + if ((which&XkbTwoLevelMask)&&(rtrn==Success)) + rtrn= XkbCopyKeyType(&from[XkbTwoLevelIndex],&to[XkbTwoLevelIndex]); + if ((which&XkbAlphabeticMask)&&(rtrn==Success)) + rtrn= XkbCopyKeyType(&from[XkbAlphabeticIndex],&to[XkbAlphabeticIndex]); + if ((which&XkbKeypadMask)&&(rtrn==Success)) { + XkbKeyTypePtr type; + rtrn= XkbCopyKeyType(&from[XkbKeypadIndex],&to[XkbKeypadIndex]); + type= &to[XkbKeypadIndex]; + if ((keypadVMod>=0)&&(keypadVMod<XkbNumVirtualMods)&&(rtrn==Success)) { + type->mods.vmods= (1<<keypadVMod); + type->map[0].active= True; + type->map[0].mods.mask= ShiftMask; + type->map[0].mods.real_mods= ShiftMask; + type->map[0].mods.vmods= 0; + type->map[0].level= 1; + type->map[1].active= False; + type->map[1].mods.mask= 0; + type->map[1].mods.real_mods= 0; + type->map[1].mods.vmods= (1<<keypadVMod); + type->map[1].level= 1; + } + } + return Success; +} + +/***====================================================================***/ + +#define CORE_SYM(i) (i<map_width?core_syms[i]:NoSymbol) +#define XKB_OFFSET(g,l) (((g)*groupsWidth)+(l)) + +int +#if NeedFunctionPrototypes +XkbKeyTypesForCoreSymbols( XkbDescPtr xkb, + int map_width, + KeySym * core_syms, + unsigned int protected, + int * types_inout, + KeySym * xkb_syms_rtrn) +#else +XkbKeyTypesForCoreSymbols(xkb,map_width,core_syms,protected,types_inout, + xkb_syms_rtrn) + XkbDescPtr xkb; + int map_width; + KeySym * core_syms; + unsigned int protected; + int * types_inout; + KeySym * xkb_syms_rtrn; +#endif +{ +register int i; +unsigned int empty; +int nSyms[XkbNumKbdGroups]; +int nGroups,tmp,groupsWidth; + + /* Section 12.2 of the protocol describes this process in more detail */ + /* Step 1: find the # of symbols in the core mapping per group */ + groupsWidth= 2; + for (i=0;i<XkbNumKbdGroups;i++) { + if ((protected&(1<<i))&&(types_inout[i]<xkb->map->num_types)) { + nSyms[i]= xkb->map->types[types_inout[i]].num_levels; + if (nSyms[i]>groupsWidth) + groupsWidth= nSyms[i]; + } + else { + types_inout[i]= XkbTwoLevelIndex; /* don't really know, yet */ + nSyms[i]= 2; + } + } + if (nSyms[XkbGroup1Index]<2) + nSyms[XkbGroup1Index]= 2; + if (nSyms[XkbGroup2Index]<2) + nSyms[XkbGroup2Index]= 2; + /* Step 2: Copy the symbols from the core ordering to XKB ordering */ + /* symbols in the core are in the order: */ + /* G1L1 G1L2 G2L1 G2L2 [G1L[3-n]] [G2L[3-n]] [G3L*] [G3L*] */ + xkb_syms_rtrn[XKB_OFFSET(XkbGroup1Index,0)]= CORE_SYM(0); + xkb_syms_rtrn[XKB_OFFSET(XkbGroup1Index,1)]= CORE_SYM(1); + for (i=2;i<nSyms[XkbGroup1Index];i++) { + xkb_syms_rtrn[XKB_OFFSET(XkbGroup1Index,i)]= CORE_SYM(2+i); + } + xkb_syms_rtrn[XKB_OFFSET(XkbGroup2Index,0)]= CORE_SYM(2); + xkb_syms_rtrn[XKB_OFFSET(XkbGroup2Index,1)]= CORE_SYM(3); + tmp= 2+(nSyms[XkbGroup1Index]-2); /* offset to extra group2 syms */ + for (i=2;i<nSyms[XkbGroup2Index];i++) { + xkb_syms_rtrn[XKB_OFFSET(XkbGroup2Index,i)]= CORE_SYM(tmp+i); + } + tmp= nSyms[XkbGroup1Index]+nSyms[XkbGroup2Index]; + if ((tmp>=map_width)&& + ((protected&(XkbExplicitKeyType3Mask|XkbExplicitKeyType4Mask))==0)) { + nSyms[XkbGroup3Index]= 0; + nSyms[XkbGroup4Index]= 0; + nGroups= 2; + } + else { + nGroups= 3; + for (i=0;i<nSyms[XkbGroup3Index];i++,tmp++) { + xkb_syms_rtrn[XKB_OFFSET(XkbGroup3Index,i)]= CORE_SYM(tmp); + } + if ((tmp<map_width)||(protected&XkbExplicitKeyType4Mask)) { + nGroups= 4; + for (i=0;i<nSyms[XkbGroup4Index];i++,tmp++) { + xkb_syms_rtrn[XKB_OFFSET(XkbGroup4Index,i)]= CORE_SYM(tmp); + } + } + else { + nSyms[XkbGroup4Index]= 0; + } + } + /* steps 3&4: alphanumeric expansion, assign canonical types */ + empty= 0; + for (i=0;i<nGroups;i++) { + KeySym *syms; + syms= &xkb_syms_rtrn[XKB_OFFSET(i,0)]; + if ((nSyms[i]>1)&&(syms[1]==NoSymbol)&&(syms[0]!=NoSymbol)) { + KeySym upper,lower; + XConvertCase(syms[0],&lower,&upper); + if (upper!=lower) { + xkb_syms_rtrn[XKB_OFFSET(i,0)]= lower; + xkb_syms_rtrn[XKB_OFFSET(i,1)]= upper; + if ((protected&(1<<i))==0) + types_inout[i]= XkbAlphabeticIndex; + } + else if ((protected&(1<<i))==0) { + types_inout[i]= XkbOneLevelIndex; + /* nSyms[i]= 1;*/ + } + } + if (((protected&(1<<i))==0)&&(types_inout[i]==XkbTwoLevelIndex)) { + if (IsKeypadKey(syms[0])||IsKeypadKey(syms[1])) + types_inout[i]= XkbKeypadIndex; + else { + KeySym upper,lower; + XConvertCase(syms[0],&lower,&upper); + if ((syms[0]==lower)&&(syms[1]==upper)) + types_inout[i]= XkbAlphabeticIndex; + } + } + if (syms[0]==NoSymbol) { + register int n; + Bool found; + for (n=1,found=False;(!found)&&(n<nSyms[i]);n++) { + found= (syms[n]!=NoSymbol); + } + if (!found) + empty|= (1<<i); + } + } + /* step 5: squoosh out empty groups */ + if (empty) { + for (i=nGroups-1;i>=0;i--) { + if (((empty&(1<<i))==0)||(protected&(1<<i))) + break; + nGroups--; + } + } + if (nGroups<1) + return 0; + + /* step 6: replicate group 1 into group two, if necessary */ + if ((nGroups>1)&&((empty&(XkbGroup1Mask|XkbGroup2Mask))==XkbGroup2Mask)) { + if ((protected&(XkbExplicitKeyType1Mask|XkbExplicitKeyType2Mask))==0) { + nSyms[XkbGroup2Index]= nSyms[XkbGroup1Index]; + types_inout[XkbGroup2Index]= types_inout[XkbGroup1Index]; + memcpy((char *)&xkb_syms_rtrn[2],(char *)xkb_syms_rtrn, + 2*sizeof(KeySym)); + } + else if (types_inout[XkbGroup1Index]==types_inout[XkbGroup2Index]) { + memcpy((char *)&xkb_syms_rtrn[nSyms[XkbGroup1Index]], + (char *)xkb_syms_rtrn, + nSyms[XkbGroup1Index]*sizeof(KeySym)); + } + } + + /* step 7: check for all groups identical or all width 1 */ + if (nGroups>1) { + Bool sameType,allOneLevel; + allOneLevel= (xkb->map->types[types_inout[0]].num_levels==1); + for (i=1,sameType=True;(allOneLevel||sameType)&&(i<nGroups);i++) { + sameType=(sameType&&(types_inout[i]==types_inout[XkbGroup1Index])); + if (allOneLevel) + allOneLevel= (xkb->map->types[types_inout[i]].num_levels==1); + } + if ((sameType)&& + (!(protected&(XkbExplicitKeyTypesMask&~XkbExplicitKeyType1Mask)))){ + register int s; + Bool identical; + for (i=1,identical=True;identical&&(i<nGroups);i++) { + KeySym *syms; + syms= &xkb_syms_rtrn[XKB_OFFSET(i,0)]; + for (s=0;identical&&(s<nSyms[i]);s++) { + if (syms[s]!=xkb_syms_rtrn[s]) + identical= False; + } + } + if (identical) + nGroups= 1; + } + if (allOneLevel && (nGroups>1)) { + KeySym *syms; + syms= &xkb_syms_rtrn[nSyms[XkbGroup1Index]]; + nSyms[XkbGroup1Index]= 1; + for (i=1;i<nGroups;i++) { + xkb_syms_rtrn[i]= syms[0]; + syms+= nSyms[i]; + nSyms[i]= 1; + } + } + } + return nGroups; +} + +static XkbSymInterpretPtr +#if NeedFunctionPrototypes +_XkbFindMatchingInterp( XkbDescPtr xkb, + KeySym sym, + unsigned int real_mods, + unsigned int level) +#else +_XkbFindMatchingInterp(xkb,sym,real_mods,level) + XkbDescPtr xkb; + KeySym sym; + unsigned int real_mods; + unsigned int level; +#endif +{ +register unsigned i; +XkbSymInterpretPtr interp,rtrn; +CARD8 mods; + + rtrn= NULL; + interp= xkb->compat->sym_interpret; + for (i=0;i<xkb->compat->num_si;i++,interp++) { + if ((interp->sym==NoSymbol)||(sym==interp->sym)) { + int match; + if ((level==0)||((interp->match&XkbSI_LevelOneOnly)==0)) + mods= real_mods; + else mods= 0; + switch (interp->match&XkbSI_OpMask) { + case XkbSI_NoneOf: + match= ((interp->mods&mods)==0); + break; + case XkbSI_AnyOfOrNone: + match= ((mods==0)||((interp->mods&mods)!=0)); + break; + case XkbSI_AnyOf: + match= ((interp->mods&mods)!=0); + break; + case XkbSI_AllOf: + match= ((interp->mods&mods)==interp->mods); + break; + case XkbSI_Exactly: + match= (interp->mods==mods); + break; + default: + match= 0; + break; + } + if (match) { + if (interp->sym!=NoSymbol) { + return interp; + } + else if (rtrn==NULL) { + rtrn= interp; + } + } + } + } + return rtrn; +} + +static void +#if NeedFunctionPrototypes +_XkbAddKeyChange(KeyCode *pFirst,unsigned char *pNum,KeyCode newKey) +#else +_XkbAddKeyChange(pFirst,pNum,newKey) + KeyCode * pFirst; + unsigned char * pNum; + KeyCode newKey; +#endif +{ +KeyCode last; + + last= (*pFirst)+(*pNum); + if (newKey<*pFirst) { + *pFirst= newKey; + *pNum= (last-newKey)+1; + } + else if (newKey>last) { + *pNum= (last-*pFirst)+1; + } + return; +} + +static void +#if NeedFunctionPrototypes +_XkbSetActionKeyMods(XkbDescPtr xkb,XkbAction *act,unsigned mods) +#else +_XkbSetActionKeyMods(xkb,act,mods) + XkbDescPtr xkb; + XkbAction * act; + unsigned mods; +#endif +{ +unsigned tmp; + + switch (act->type) { + case XkbSA_SetMods: case XkbSA_LatchMods: case XkbSA_LockMods: + if (act->mods.flags&XkbSA_UseModMapMods) + act->mods.real_mods= act->mods.mask= mods; + if ((tmp= XkbModActionVMods(&act->mods))!=0) { + XkbVirtualModsToReal(xkb,tmp,&tmp); + act->mods.mask|= tmp; + } + break; + case XkbSA_ISOLock: + if (act->iso.flags&XkbSA_UseModMapMods) + act->iso.real_mods= act->iso.mask= mods; + if ((tmp= XkbModActionVMods(&act->iso))!=0) { + XkbVirtualModsToReal(xkb,tmp,&tmp); + act->iso.mask|= tmp; + } + break; + } + return; +} + +#define IBUF_SIZE 8 + +Bool +#if NeedFunctionPrototypes +XkbApplyCompatMapToKey(XkbDescPtr xkb,KeyCode key,XkbChangesPtr changes) +#else +XkbApplyCompatMapToKey(xkb,key,changes) + XkbDescPtr xkb; + KeyCode key; + XkbChangesPtr changes; +#endif +{ +KeySym * syms; +unsigned char explicit,mods; +XkbSymInterpretPtr *interps,ibuf[IBUF_SIZE]; +int n,nSyms,found; +unsigned changed,tmp; + + if ((!xkb)||(!xkb->map)||(!xkb->map->key_sym_map)|| + (!xkb->compat)||(!xkb->compat->sym_interpret)|| + (key<xkb->min_key_code)||(key>xkb->max_key_code)) { + return False; + } + if (((!xkb->server)||(!xkb->server->key_acts))&& + (XkbAllocServerMap(xkb,XkbAllServerInfoMask,0)!=Success)) { + return False; + } + changed= 0; /* keeps track of what has changed in _this_ call */ + explicit= xkb->server->explicit[key]; + if (explicit&XkbExplicitInterpretMask) /* nothing to do */ + return True; + mods= (xkb->map->modmap?xkb->map->modmap[key]:0); + nSyms= XkbKeyNumSyms(xkb,key); + syms= XkbKeySymsPtr(xkb,key); + if (nSyms>IBUF_SIZE) { + interps= _XkbTypedCalloc(nSyms,XkbSymInterpretPtr); + if (interps==NULL) { + interps= ibuf; + nSyms= IBUF_SIZE; + } + } + else { + interps= ibuf; + } + found= 0; + for (n=0;n<nSyms;n++) { + unsigned level= (n%XkbKeyGroupsWidth(xkb,key)); + interps[n]= NULL; + if (syms[n]!=NoSymbol) { + interps[n]= _XkbFindMatchingInterp(xkb,syms[n],mods,level); + if (interps[n]&&interps[n]->act.type!=XkbSA_NoAction) + found++; + else interps[n]= NULL; + } + } + /* 1/28/96 (ef) -- XXX! WORKING HERE */ + if (!found) { + if (xkb->server->key_acts[key]!=0) { + xkb->server->key_acts[key]= 0; + changed|= XkbKeyActionsMask; + } + } + else { + XkbAction *pActs; + unsigned int new_vmodmask; + changed|= XkbKeyActionsMask; + pActs= XkbResizeKeyActions(xkb,key,nSyms); + if (!pActs) + return False; + new_vmodmask= 0; + for (n=0;n<nSyms;n++) { + if (interps[n]) { + unsigned effMods; + + pActs[n]= *((XkbAction *)&interps[n]->act); + if ((n==0)||((interps[n]->match&XkbSI_LevelOneOnly)==0)) { + effMods= mods; + if (interps[n]->virtual_mod!=XkbNoModifier) + new_vmodmask|= (1<<interps[n]->virtual_mod); + } + else effMods= 0; + _XkbSetActionKeyMods(xkb,&pActs[n],effMods); + } + else pActs[n].type= XkbSA_NoAction; + } + if (((explicit&XkbExplicitVModMapMask)==0)&& + (xkb->server->vmodmap[key]!=new_vmodmask)) { + changed|= XkbVirtualModMapMask; + xkb->server->vmodmap[key]= new_vmodmask; + } + if (interps[0]) { + if ((interps[0]->flags&XkbSI_LockingKey)&& + ((explicit&XkbExplicitBehaviorMask)==0)) { + xkb->server->behaviors[key].type= XkbKB_Lock; + changed|= XkbKeyBehaviorsMask; + } + if (((explicit&XkbExplicitAutoRepeatMask)==0)&&(xkb->ctrls)) { + CARD8 old; + old= xkb->ctrls->per_key_repeat[key/8]; + if (interps[0]->flags&XkbSI_AutoRepeat) + xkb->ctrls->per_key_repeat[key/8]|= (1<<(key%8)); + else xkb->ctrls->per_key_repeat[key/8]&= ~(1<<(key%8)); + if (changes && (old!=xkb->ctrls->per_key_repeat[key/8])) + changes->ctrls.changed_ctrls|= XkbPerKeyRepeatMask; + } + } + } + if ((!found)||(interps[0]==NULL)) { + if (((explicit&XkbExplicitAutoRepeatMask)==0)&&(xkb->ctrls)) { + CARD8 old; + old= xkb->ctrls->per_key_repeat[key/8]; +#if RETURN_SHOULD_REPEAT + if (*XkbKeySymsPtr(xkb,key) != XK_Return) +#endif + xkb->ctrls->per_key_repeat[key/8]|= (1<<(key%8)); + if (changes && (old!=xkb->ctrls->per_key_repeat[key/8])) + changes->ctrls.changed_ctrls|= XkbPerKeyRepeatMask; + } + if (((explicit&XkbExplicitBehaviorMask)==0)&& + (xkb->server->behaviors[key].type==XkbKB_Lock)) { + xkb->server->behaviors[key].type= XkbKB_Default; + changed|= XkbKeyBehaviorsMask; + } + } + if (changes) { + XkbMapChangesPtr mc; + mc= &changes->map; + tmp= (changed&mc->changed); + if (tmp&XkbKeyActionsMask) + _XkbAddKeyChange(&mc->first_key_act,&mc->num_key_acts,key); + else if (changed&XkbKeyActionsMask) { + mc->changed|= XkbKeyActionsMask; + mc->first_key_act= key; + mc->num_key_acts= 1; + } + if (tmp&XkbKeyBehaviorsMask) { + _XkbAddKeyChange(&mc->first_key_behavior,&mc->num_key_behaviors, + key); + } + else if (changed&XkbKeyBehaviorsMask) { + mc->changed|= XkbKeyBehaviorsMask; + mc->first_key_behavior= key; + mc->num_key_behaviors= 1; + } + if (tmp&XkbVirtualModMapMask) + _XkbAddKeyChange(&mc->first_vmodmap_key,&mc->num_vmodmap_keys,key); + else if (changed&XkbVirtualModMapMask) { + mc->changed|= XkbVirtualModMapMask; + mc->first_vmodmap_key= key; + mc->num_vmodmap_keys= 1; + } + mc->changed|= changed; + } + if (interps!=ibuf) + _XkbFree(interps); + return True; +} + +Bool +#if NeedFunctionPrototypes +XkbUpdateMapFromCore( XkbDescPtr xkb, + KeyCode first_key, + int num_keys, + int map_width, + KeySym * core_keysyms, + XkbChangesPtr changes) +#else +XkbUpdateMapFromCore(xkb,first_key,num_keys,map_width,core_keysyms,changes) + XkbDescPtr xkb; + KeyCode first_key; + int num_keys; + int map_width; + KeySym * core_keysyms; + XkbChangesPtr changes; +#endif +{ +register int key,last_key; +KeySym * syms; + + syms= &core_keysyms[(first_key-xkb->min_key_code)*map_width]; + if (changes) { + if (changes->map.changed&XkbKeySymsMask) { + _XkbAddKeyChange(&changes->map.first_key_sym, + &changes->map.num_key_syms,first_key); + if (num_keys>1) { + _XkbAddKeyChange(&changes->map.first_key_sym, + &changes->map.num_key_syms, + first_key+num_keys-1); + } + } + else { + changes->map.changed|= XkbKeySymsMask; + changes->map.first_key_sym= first_key; + changes->map.num_key_syms= num_keys; + } + } + last_key= first_key+num_keys-1; + for (key=first_key;key<=last_key;key++,syms+= map_width) { + XkbMapChangesPtr mc; + unsigned explicit; + KeySym tsyms[XkbMaxSymsPerKey]; + int types[XkbNumKbdGroups]; + int nG; + + explicit= xkb->server->explicit[key]&XkbExplicitKeyTypesMask; + types[XkbGroup1Index]= XkbKeyKeyTypeIndex(xkb,key,XkbGroup1Index); + types[XkbGroup2Index]= XkbKeyKeyTypeIndex(xkb,key,XkbGroup2Index); + types[XkbGroup3Index]= XkbKeyKeyTypeIndex(xkb,key,XkbGroup3Index); + types[XkbGroup4Index]= XkbKeyKeyTypeIndex(xkb,key,XkbGroup4Index); + nG= XkbKeyTypesForCoreSymbols(xkb,map_width,syms,explicit,types,tsyms); + if (changes) + mc= &changes->map; + else mc= NULL; + XkbChangeTypesOfKey(xkb,key,nG,XkbAllGroupsMask,types,mc); + memcpy((char *)XkbKeySymsPtr(xkb,key),(char *)tsyms, + XkbKeyNumSyms(xkb,key)*sizeof(KeySym)); + XkbApplyCompatMapToKey(xkb,key,changes); + } + + if ((xkb->server->vmods!=NULL)&&(xkb->map->modmap!=NULL)&&(changes)&& + (changes->map.changed&(XkbVirtualModMapMask|XkbModifierMapMask))) { + unsigned char newVMods[XkbNumVirtualMods]; + register unsigned bit,i; + unsigned present; + + bzero(newVMods,XkbNumVirtualMods); + present= 0; + for (key=xkb->min_key_code;key<=xkb->max_key_code;key++) { + if (xkb->server->vmodmap[key]==0) + continue; + for (i=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) { + if (bit&xkb->server->vmodmap[key]) { + present|= bit; + newVMods[i]|= xkb->map->modmap[key]; + } + } + } + for (i=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) { + if ((bit&present)&&(newVMods[i]!=xkb->server->vmods[i])) { + changes->map.changed|= XkbVirtualModsMask; + changes->map.vmods|= bit; + xkb->server->vmods[i]= newVMods[i]; + } + } + } + if (changes && (changes->map.changed&XkbVirtualModsMask)) + XkbApplyVirtualModChanges(xkb,changes->map.vmods,changes); + return True; +} + +Status +#if NeedFunctionPrototypes +XkbChangeTypesOfKey( XkbDescPtr xkb, + int key, + int nGroups, + unsigned groups, + int * newTypesIn, + XkbMapChangesPtr changes) +#else +XkbChangeTypesOfKey(xkb,key,nGroups,groups,newTypesIn,changes) + XkbDescPtr xkb; + int key; + int nGroups; + unsigned groups; + int * newTypesIn; + XkbMapChangesPtr changes; +#endif +{ +XkbKeyTypePtr pOldType,pNewType; +register int i; +int width,nOldGroups,oldWidth,newTypes[XkbNumKbdGroups]; + + if ((!xkb) || (!XkbKeycodeInRange(xkb,key)) || (!xkb->map) || + (!xkb->map->types)||(!newTypes)||((groups&XkbAllGroupsMask)==0)|| + (nGroups>XkbNumKbdGroups)) { + return BadMatch; + } + if (nGroups==0) { + for (i=0;i<XkbNumKbdGroups;i++) { + xkb->map->key_sym_map[key].kt_index[i]= XkbOneLevelIndex; + } + i= xkb->map->key_sym_map[key].group_info; + i= XkbSetNumGroups(i,0); + xkb->map->key_sym_map[key].group_info= i; + XkbResizeKeySyms(xkb,key,0); + return Success; + } + + nOldGroups= XkbKeyNumGroups(xkb,key); + oldWidth= XkbKeyGroupsWidth(xkb,key); + for (width=i=0;i<nGroups;i++) { + if (groups&(1<<i)) + newTypes[i]= newTypesIn[i]; + else if (i<nOldGroups) + newTypes[i]= XkbKeyKeyTypeIndex(xkb,key,i); + else if (nOldGroups>0) + newTypes[i]= XkbKeyKeyTypeIndex(xkb,key,XkbGroup1Index); + else newTypes[i]= XkbTwoLevelIndex; + if (newTypes[i]>xkb->map->num_types) + return BadMatch; + pNewType= &xkb->map->types[newTypes[i]]; + if (pNewType->num_levels>width) + width= pNewType->num_levels; + } + if ((xkb->ctrls)&&(nGroups>xkb->ctrls->num_groups)) + xkb->ctrls->num_groups= nGroups; + if ((width!=oldWidth)||(nGroups!=nOldGroups)) { + KeySym oldSyms[XkbMaxSymsPerKey],*pSyms; + int nCopy; + + if (nOldGroups==0) { + pSyms= XkbResizeKeySyms(xkb,key,width*nGroups); + if (pSyms!=NULL) { + i= xkb->map->key_sym_map[key].group_info; + i= XkbSetNumGroups(i,nGroups); + xkb->map->key_sym_map[key].group_info= i; + xkb->map->key_sym_map[key].width= width; + for (i=0;i<nGroups;i++) { + xkb->map->key_sym_map[key].kt_index[i]= newTypes[i]; + } + return Success; + } + return BadAlloc; + } + pSyms= XkbKeySymsPtr(xkb,key); + memcpy(oldSyms,pSyms,XkbKeyNumSyms(xkb,key)*sizeof(KeySym)); + pSyms= XkbResizeKeySyms(xkb,key,width*nGroups); + if (pSyms==NULL) + return BadAlloc; + bzero(pSyms,width*nGroups*sizeof(KeySym)); + for (i=0;(i<nGroups)&&(i<nOldGroups);i++) { + pOldType= XkbKeyKeyType(xkb,key,i); + pNewType= &xkb->map->types[newTypes[i]]; + if (pNewType->num_levels>pOldType->num_levels) + nCopy= pOldType->num_levels; + else nCopy= pNewType->num_levels; + memcpy(&pSyms[i*width],&oldSyms[i*oldWidth],nCopy*sizeof(KeySym)); + } + if (XkbKeyHasActions(xkb,key)) { + XkbAction oldActs[XkbMaxSymsPerKey],*pActs; + pActs= XkbKeyActionsPtr(xkb,key); + memcpy(oldActs,pActs,XkbKeyNumSyms(xkb,key)*sizeof(XkbAction)); + pActs= XkbResizeKeyActions(xkb,key,width*nGroups); + if (pActs==NULL) + return BadAlloc; + bzero(pActs,width*nGroups*sizeof(XkbAction)); + for (i=0;(i<nGroups)&&(i<nOldGroups);i++) { + pOldType= XkbKeyKeyType(xkb,key,i); + pNewType= &xkb->map->types[newTypes[i]]; + if (pNewType->num_levels>pOldType->num_levels) + nCopy= pOldType->num_levels; + else nCopy= pNewType->num_levels; + memcpy(&pActs[i*width],&oldActs[i*oldWidth], + nCopy*sizeof(XkbAction)); + } + } + i= xkb->map->key_sym_map[key].group_info; + i= XkbSetNumGroups(i,nGroups); + xkb->map->key_sym_map[key].group_info= i; + xkb->map->key_sym_map[key].width= width; + } + width= 0; + for (i=0;i<nGroups;i++) { + xkb->map->key_sym_map[key].kt_index[i]= newTypes[i]; + if (xkb->map->types[newTypes[i]].num_levels>width) + width= xkb->map->types[newTypes[i]].num_levels; + } + xkb->map->key_sym_map[key].width= width; + if (changes!=NULL) { + if (changes->changed&XkbKeySymsMask) { + _XkbAddKeyChange(&changes->first_key_sym,&changes->num_key_syms, + key); + } + else { + changes->changed|= XkbKeySymsMask; + changes->first_key_sym= key; + changes->num_key_syms= 1; + } + } + return Success; +} + +/***====================================================================***/ + +Bool +#if NeedFunctionPrototypes +XkbVirtualModsToReal(XkbDescPtr xkb,unsigned virtual_mask,unsigned *mask_rtrn) +#else +XkbVirtualModsToReal(xkb,virtual_mask,mask_rtrn) + XkbDescPtr xkb; + unsigned virtual_mask; + unsigned * mask_rtrn; +#endif +{ +register int i,bit; +register unsigned mask; + + if (xkb==NULL) + return False; + if (virtual_mask==0) { + *mask_rtrn= 0; + return True; + } + if (xkb->server==NULL) + return False; + for (i=mask=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) { + if (virtual_mask&bit) + mask|= xkb->server->vmods[i]; + } + *mask_rtrn= mask; + return True; +} + +/***====================================================================***/ + +Bool +#if NeedFunctionPrototypes +XkbUpdateActionVirtualMods(XkbDescPtr xkb,XkbAction *act,unsigned changed) +#else +XkbUpdateActionVirtualMods(xkb,act,changed) + XkbDescPtr xkb; + XkbAction * act; + unsigned changed; +#endif +{ +unsigned int tmp; + + switch (act->type) { + case XkbSA_SetMods: case XkbSA_LatchMods: case XkbSA_LockMods: + if (((tmp= XkbModActionVMods(&act->mods))&changed)!=0) { + XkbVirtualModsToReal(xkb,tmp,&tmp); + act->mods.mask= act->mods.real_mods; + act->mods.mask|= tmp; + return True; + } + break; + case XkbSA_ISOLock: + if ((((tmp= XkbModActionVMods(&act->iso))!=0)&changed)!=0) { + XkbVirtualModsToReal(xkb,tmp,&tmp); + act->iso.mask= act->iso.real_mods; + act->iso.mask|= tmp; + return True; + } + break; + } + return False; +} + +void +#if NeedFunctionPrototypes +XkbUpdateKeyTypeVirtualMods( XkbDescPtr xkb, + XkbKeyTypePtr type, + unsigned int changed, + XkbChangesPtr changes) +#else +XkbUpdateKeyTypeVirtualMods(xkb,type,changed,changes) + XkbDescPtr xkb; + XkbKeyTypePtr type; + unsigned int changed; + XkbChangesPtr changes; +#endif +{ +register unsigned int i; +unsigned int mask; + + XkbVirtualModsToReal(xkb,type->mods.vmods,&mask); + type->mods.mask= type->mods.real_mods|mask; + if ((type->map_count>0)&&(type->mods.vmods!=0)) { + XkbKTMapEntryPtr entry; + for (i=0,entry=type->map;i<type->map_count;i++,entry++) { + if (entry->mods.vmods!=0) { + XkbVirtualModsToReal(xkb,entry->mods.vmods,&mask); + entry->mods.mask=entry->mods.real_mods|mask; + /* entry is active if vmods are bound*/ + entry->active= (mask!=0); + } + else entry->active= 1; + } + } + if (changes) { + int type_ndx; + type_ndx= type-xkb->map->types; + if ((type_ndx<0)||(type_ndx>xkb->map->num_types)) + return; + if (changes->map.changed&XkbKeyTypesMask) { + int last; + last= changes->map.first_type+changes->map.num_types-1; + if (type_ndx<changes->map.first_type) { + changes->map.first_type= type_ndx; + changes->map.num_types= (last-type_ndx)+1; + } + else if (type_ndx>last) { + changes->map.num_types= (type_ndx-changes->map.first_type)+1; + } + } + else { + changes->map.changed|= XkbKeyTypesMask; + changes->map.first_type= type_ndx; + changes->map.num_types= 1; + } + } + return; +} + +Bool +#if NeedFunctionPrototypes +XkbApplyVirtualModChanges(XkbDescPtr xkb,unsigned changed,XkbChangesPtr changes) +#else +XkbApplyVirtualModChanges(xkb,changed,changes) + XkbDescPtr xkb; + unsigned changed; + XkbChangesPtr changes; +#endif +{ +register int i; +unsigned checkState; + + if ((!xkb) || (!xkb->map) || (changed==0)) + return False; + for (i=0;i<xkb->map->num_types;i++) { + if (xkb->map->types[i].mods.vmods & changed) + XkbUpdateKeyTypeVirtualMods(xkb,&xkb->map->types[i],changed,changes); + } + if (changed&xkb->ctrls->internal.vmods) { + unsigned int newMask; + XkbVirtualModsToReal(xkb,xkb->ctrls->internal.vmods,&newMask); + newMask|= xkb->ctrls->internal.real_mods; + if (xkb->ctrls->internal.mask!=newMask) { + xkb->ctrls->internal.mask= newMask; + if (changes) { + changes->ctrls.changed_ctrls|= XkbInternalModsMask; + checkState= True; + } + } + } + if (changed&xkb->ctrls->ignore_lock.vmods) { + unsigned int newMask; + XkbVirtualModsToReal(xkb,xkb->ctrls->ignore_lock.vmods,&newMask); + newMask|= xkb->ctrls->ignore_lock.real_mods; + if (xkb->ctrls->ignore_lock.mask!=newMask) { + xkb->ctrls->ignore_lock.mask= newMask; + if (changes) { + changes->ctrls.changed_ctrls|= XkbIgnoreLockModsMask; + checkState= True; + } + } + } + if (xkb->indicators!=NULL) { + XkbIndicatorMapPtr map; + map= &xkb->indicators->maps[0]; + for (i=0;i<XkbNumIndicators;i++,map++) { + if (map->mods.vmods&changed) { + unsigned int newMask; + XkbVirtualModsToReal(xkb,map->mods.vmods,&newMask); + newMask|= map->mods.real_mods; + if (newMask!=map->mods.mask) { + map->mods.mask= newMask; + if (changes) { + changes->indicators.map_changes|= (1<<i); + checkState= True; + } + } + } + } + } + if (xkb->compat!=NULL) { + XkbCompatMapPtr compat; + compat= xkb->compat; + for (i=0;i<XkbNumKbdGroups;i++) { + unsigned int newMask; + XkbVirtualModsToReal(xkb,compat->groups[i].vmods,&newMask); + newMask|= compat->groups[i].real_mods; + if (compat->groups[i].mask!=newMask) { + compat->groups[i].mask= newMask; + if (changes) { + changes->compat.changed_groups|= (1<<i); + checkState= True; + } + } + } + } + if (xkb->map && xkb->server) { + int highChange,lowChange; + lowChange= -1; + for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) { + if (XkbKeyHasActions(xkb,i)) { + register XkbAction *pAct; + register int n; + + pAct= XkbKeyActionsPtr(xkb,i); + for (n=XkbKeyNumActions(xkb,i);n>0;n--,pAct++) { + if ((pAct->type!=XkbSA_NoAction)&& + XkbUpdateActionVirtualMods(xkb,pAct,changed)) { + if (lowChange<0) + lowChange= i; + highChange= i; + } + } + } + } + if (changes && (lowChange>0)) { /* something changed */ + if (changes->map.changed&XkbKeyActionsMask) { + int last; + if (changes->map.first_key_act<lowChange) + lowChange= changes->map.first_key_act; + last= changes->map.first_key_act+changes->map.num_key_acts-1; + if (last>highChange) + highChange= last; + } + changes->map.changed|= XkbKeyActionsMask; + changes->map.first_key_act= lowChange; + changes->map.num_key_acts= (highChange-lowChange)+1; + } + } + return checkState; +} diff --git a/src/xkb/XKBNames.c b/src/xkb/XKBNames.c new file mode 100644 index 00000000..22439d29 --- /dev/null +++ b/src/xkb/XKBNames.c @@ -0,0 +1,953 @@ +/* $Xorg: XKBNames.c,v 1.3 2000/08/17 19:45:02 cpqbld Exp $ */ +/************************************************************ +Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc. + +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 Silicon Graphics not be +used in advertising or publicity pertaining to distribution +of the software without specific prior written permission. +Silicon Graphics makes no representation about the suitability +of this software for any purpose. It is provided "as is" +without any express or implied warranty. + +SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS +SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON +GRAPHICS 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. + +********************************************************/ + +#define NEED_REPLIES +#define NEED_EVENTS +#include "Xlibint.h" +#include <X11/extensions/XKBproto.h> +#include "XKBlibint.h" + + +static Status +#if NeedFunctionPrototypes +_XkbReadAtoms( XkbReadBufferPtr buf, + Atom * atoms, + int maxAtoms, + CARD32 present) +#else +_XkbReadAtoms(buf,atoms,maxAtoms,present) + XkbReadBufferPtr buf; + Atom *atoms; + int maxAtoms; + CARD32 present; +#endif +{ +register int i,bit; + + for (i=0,bit=1;(i<maxAtoms)&&(present);i++,bit<<=1) { + if (present&bit) { + if (!_XkbReadBufferCopy32(buf,(long *)&atoms[i],1)) + return BadLength; + present&= ~bit; + } + } + return Success; +} + +Status +#if NeedFunctionPrototypes +_XkbReadGetNamesReply( Display * dpy, + xkbGetNamesReply * rep, + XkbDescPtr xkb, + int * nread_rtrn) +#else +_XkbReadGetNamesReply(dpy,rep,xkb,nread_rtrn) + Display * dpy; + xkbGetNamesReply * rep; + XkbDescPtr xkb; + int * nread_rtrn; +#endif +{ + int i,len; + XkbReadBufferRec buf; + register XkbNamesPtr names; + + if ( xkb->device_spec == XkbUseCoreKbd ) + xkb->device_spec = rep->deviceID; + + if ((xkb->names==NULL)&& + (XkbAllocNames(xkb,rep->which, + rep->nRadioGroups,rep->nKeyAliases)!=Success)) { + return BadAlloc; + } + names= xkb->names; + if (rep->length==0) + return Success; + + if (!_XkbInitReadBuffer(dpy,&buf,(int)rep->length*4)) + return BadAlloc; + if (nread_rtrn) + *nread_rtrn= (int)rep->length*4; + + if ((rep->which&XkbKeycodesNameMask)&& + (!_XkbReadBufferCopy32(&buf,(long *)&names->keycodes,1))) + goto BAILOUT; + if ((rep->which&XkbGeometryNameMask)&& + (!_XkbReadBufferCopy32(&buf,(long *)&names->geometry,1))) + goto BAILOUT; + if ((rep->which&XkbSymbolsNameMask)&& + (!_XkbReadBufferCopy32(&buf,(long *)&names->symbols,1))) + goto BAILOUT; + if ((rep->which&XkbPhysSymbolsNameMask)&& + (!_XkbReadBufferCopy32(&buf,(long *)&names->phys_symbols,1))) + goto BAILOUT; + if ((rep->which&XkbTypesNameMask)&& + (!_XkbReadBufferCopy32(&buf,(long *)&names->types,1))) + goto BAILOUT; + if ((rep->which&XkbCompatNameMask)&& + (!_XkbReadBufferCopy32(&buf,(long *)&names->compat,1))) + goto BAILOUT; + + if ( rep->which & XkbKeyTypeNamesMask ) { + XkbClientMapPtr map= xkb->map; + XkbKeyTypePtr type; + + len= rep->nTypes*4; + if (map!=NULL) { + type= map->types; + for (i=0;(i<map->num_types)&&(i<rep->nTypes);i++,type++) { + if (!_XkbReadBufferCopy32(&buf,(long *)&type->name,1)) + goto BAILOUT; + len-= 4; + } + } + if ((len>0)&&(!_XkbSkipReadBufferData(&buf,len))) + goto BAILOUT; + } + if ( rep->which&XkbKTLevelNamesMask ) { + CARD8 *nLevels; + XkbClientMapPtr map= xkb->map; + XkbKeyTypePtr type; + + nLevels=(CARD8*)_XkbGetReadBufferPtr(&buf,XkbPaddedSize(rep->nTypes)); + if (nLevels==NULL) + goto BAILOUT; + if (map!=NULL) { + type= map->types; + for (i=0;i<(int)rep->nTypes;i++,type++) { + if (i>=map->num_types) { + if (!_XkbSkipReadBufferData(&buf,nLevels[i]*4)) + goto BAILOUT; + continue; + } + if ((nLevels[i]>0)&&(nLevels[i]!=type->num_levels)) { + goto BAILOUT; + } + if (type->level_names!=NULL) + Xfree(type->level_names); + if (nLevels[i]==0) { + type->level_names= NULL; + continue; + } + type->level_names= _XkbTypedCalloc(nLevels[i],Atom); + if (type->level_names!=NULL) { + if (!_XkbReadBufferCopy32(&buf,(long *)type->level_names, + nLevels[i])) + goto BAILOUT; + } + else { + _XkbSkipReadBufferData(&buf,nLevels[i]*4); + } + } + } + else { + for (i=0;i<(int)rep->nTypes;i++) { + _XkbSkipReadBufferData(&buf,nLevels[i]*4); + } + } + } + if (rep->which & XkbIndicatorNamesMask) { + if (_XkbReadAtoms(&buf,names->indicators,XkbNumIndicators, + rep->indicators)!=Success) + goto BAILOUT; + } + if ( rep->which&XkbVirtualModNamesMask ) { + if (_XkbReadAtoms(&buf,names->vmods,XkbNumVirtualMods, + (CARD32)rep->virtualMods)!=Success) + goto BAILOUT; + } + if ( rep->which&XkbGroupNamesMask ) { + if (_XkbReadAtoms(&buf,names->groups,XkbNumKbdGroups, + (CARD32)rep->groupNames)!=Success) + goto BAILOUT; + } + if ( rep->which&XkbKeyNamesMask ) { + if (names->keys==NULL) { + int nKeys; + if (xkb->max_key_code==0) { + xkb->min_key_code= rep->minKeyCode; + xkb->max_key_code= rep->maxKeyCode; + } + nKeys= xkb->max_key_code+1; + names->keys= _XkbTypedCalloc(nKeys,XkbKeyNameRec); + } + if (names->keys!=NULL) { + if (!_XkbCopyFromReadBuffer(&buf, + (char *)&names->keys[rep->firstKey], + rep->nKeys*XkbKeyNameLength)) + goto BAILOUT; + } + else _XkbSkipReadBufferData(&buf,rep->nKeys*XkbKeyNameLength); + } + if ( rep->which&XkbKeyAliasesMask && (rep->nKeyAliases>0) ) { + if (XkbAllocNames(xkb,XkbKeyAliasesMask,0,rep->nKeyAliases)!=Success) + goto BAILOUT; + if (!_XkbCopyFromReadBuffer(&buf,(char *)names->key_aliases, + rep->nKeyAliases*XkbKeyNameLength*2)) + goto BAILOUT; + } + if ( rep->which&XkbRGNamesMask ) { + if (rep->nRadioGroups>0) { + Atom *rgNames; + + if (names->radio_groups==NULL) + names->radio_groups = _XkbTypedCalloc(rep->nRadioGroups,Atom); + else if (names->num_rg<rep->nRadioGroups) { + names->radio_groups = _XkbTypedRealloc(names->radio_groups, + rep->nRadioGroups, + Atom); + } + rgNames= names->radio_groups; + if (!rgNames) { + goto BAILOUT; + } + if (!_XkbReadBufferCopy32(&buf,(long *)rgNames,rep->nRadioGroups)) + goto BAILOUT; + names->num_rg= rep->nRadioGroups; + } + else if (names->num_rg>0) { + names->num_rg= 0; + Xfree(names->radio_groups); + } + } + len= _XkbFreeReadBuffer(&buf); + if (len!=0) return BadLength; + else return Success; +BAILOUT: + _XkbFreeReadBuffer(&buf); + return BadLength; +} + +Status +#if NeedFunctionPrototypes +XkbGetNames(Display *dpy,unsigned which,XkbDescPtr xkb) +#else +XkbGetNames(dpy,which,xkb) + Display * dpy; + unsigned which; + XkbDescPtr xkb; +#endif +{ + register xkbGetNamesReq *req; + xkbGetNamesReply rep; + Status status; + XkbInfoPtr xkbi; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) + return BadAccess; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + if (!xkb->names) { + xkb->names = _XkbTypedCalloc(1,XkbNamesRec); + if (!xkb->names) { + UnlockDisplay(dpy); + SyncHandle(); + return BadAlloc; + } + } + GetReq(kbGetNames, req); + req->reqType = xkbi->codes->major_opcode; + req->xkbReqType = X_kbGetNames; + req->deviceSpec = xkb->device_spec; + req->which = which; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return BadImplementation; + } + + status = _XkbReadGetNamesReply(dpy,&rep,xkb,NULL); + UnlockDisplay(dpy); + SyncHandle(); + return status; +} + +/***====================================================================***/ + +static int +#if NeedFunctionPrototypes +_XkbCountBits(int nBitsMax,unsigned long mask) +#else +_XkbCountBits(nBitsMax,mask) + int nBitsMax; + unsigned long mask; +#endif +{ +register unsigned long y, nBits; + + y = (mask >> 1) &033333333333; + y = mask - y - ((y >>1) & 033333333333); + nBits = ((unsigned int) (((y + (y >> 3)) & 030707070707) % 077)); + + /* nBitsMax really means max+1 */ + return (nBits < nBitsMax) ? nBits : (nBitsMax - 1); +} + +static CARD32 +#if NeedFunctionPrototypes +_XkbCountAtoms(Atom *atoms,int maxAtoms,int *count) +#else +_XkbCountAtoms(atoms,maxAtoms,count) + Atom *atoms; + int maxAtoms; + int *count; +#endif +{ +register unsigned int i,bit,nAtoms; +register CARD32 atomsPresent; + + for (i=nAtoms=atomsPresent=0,bit=1;i<maxAtoms;i++,bit<<=1) { + if (atoms[i]!=None) { + atomsPresent|= bit; + nAtoms++; + } + } + if (count) + *count= nAtoms; + return atomsPresent; +} + +static void +#if NeedFunctionPrototypes +_XkbCopyAtoms(Display *dpy,Atom *atoms,CARD32 mask,int maxAtoms) +#else +_XkbCopyAtoms(dpy,atoms,mask,maxAtoms) + Display * dpy; + Atom * atoms; + CARD32 mask; + int maxAtoms; +#endif +{ +register unsigned int i,bit; + + for (i=0,bit=1;i<maxAtoms;i++,bit<<=1) { + if (mask&bit) + Data32(dpy,&atoms[i],4); + } + return; +} + +Bool +#if NeedFunctionPrototypes +XkbSetNames( Display * dpy, + unsigned int which, + unsigned int firstType, + unsigned int nTypes, + XkbDescPtr xkb) +#else +XkbSetNames(dpy,which,firstType,nTypes,xkb) + Display * dpy; + unsigned int which; + unsigned int firstType; + unsigned int nTypes; + XkbDescPtr xkb; +#endif +{ + register xkbSetNamesReq *req; + int nLvlNames; + XkbInfoPtr xkbi; + XkbNamesPtr names; + unsigned firstLvlType,nLvlTypes; + int nVMods,nLEDs,nRG,nKA,nGroups; + int nKeys,firstKey,nAtoms; + CARD32 leds,vmods,groups; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) + return False; + if ((!xkb)||(!xkb->names)) + return False; + firstLvlType= firstType; + nLvlTypes= nTypes; + if (nTypes<1) + which&= ~(XkbKTLevelNamesMask|XkbKeyTypeNamesMask); + else if (firstType<=XkbLastRequiredType) { + int adjust; + adjust= XkbLastRequiredType-firstType+1; + firstType+= adjust; + nTypes-= adjust; + if (nTypes<1) + which&= ~XkbKeyTypeNamesMask; + } + names= xkb->names; + if (which&(XkbKTLevelNamesMask|XkbKeyTypeNamesMask)) { + register int i; + XkbKeyTypePtr type; + if((xkb->map==NULL)||(xkb->map->types==NULL)||(nTypes==0)|| + (firstType+nTypes>xkb->map->num_types)|| + (firstLvlType+nLvlTypes>xkb->map->num_types)) + return False; + if (which&XkbKTLevelNamesMask) { + type= &xkb->map->types[firstLvlType]; + for (i=nLvlNames=0;i<nLvlTypes;i++,type++) { + if (type->level_names!=NULL) + nLvlNames+= type->num_levels; + } + } + } + + nVMods= nLEDs= nRG= nKA= nAtoms= nGroups= 0; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbSetNames, req); + req->reqType = xkbi->codes->major_opcode; + req->xkbReqType = X_kbSetNames; + req->deviceSpec = xkb->device_spec; + req->firstType = firstType; + req->nTypes = nTypes; + req->firstKey = xkb->min_key_code; + req->nKeys = xkb->max_key_code-xkb->min_key_code+1; + + if (which&XkbKeycodesNameMask) + nAtoms++; + if (which&XkbGeometryNameMask) + nAtoms++; + if (which&XkbSymbolsNameMask) + nAtoms++; + if (which&XkbPhysSymbolsNameMask) + nAtoms++; + if (which&XkbTypesNameMask) + nAtoms++; + if (which&XkbCompatNameMask) + nAtoms++; + if (which&XkbKeyTypeNamesMask) + nAtoms+= nTypes; + if (which&XkbKTLevelNamesMask) { + req->firstKTLevel= firstLvlType; + req->nKTLevels= nLvlTypes; + req->length+= XkbPaddedSize(nLvlTypes)/4; /* room for group widths */ + nAtoms+= nLvlNames; + } + else req->firstKTLevel= req->nKTLevels= 0; + + if (which&XkbIndicatorNamesMask) { + req->indicators= leds= + _XkbCountAtoms(names->indicators,XkbNumIndicators,&nLEDs); + if (nLEDs>0) + nAtoms+= nLEDs; + else which&= ~XkbIndicatorNamesMask; + } + else req->indicators= leds= 0; + + if (which&XkbVirtualModNamesMask) { + vmods= req->virtualMods= (CARD16) + _XkbCountAtoms(names->vmods,XkbNumVirtualMods,&nVMods); + if (nVMods>0) + nAtoms+= nVMods; + else which&= ~XkbVirtualModNamesMask; + } + else vmods= req->virtualMods= 0; + + if (which&XkbGroupNamesMask) { + groups= req->groupNames= (CARD8) + _XkbCountAtoms(names->groups,XkbNumKbdGroups,&nGroups); + if (nGroups>0) + nAtoms+= nGroups; + else which&= ~XkbGroupNamesMask; + } + else groups= req->groupNames= 0; + + if ((which&XkbKeyNamesMask)&&(names->keys!=NULL)) { + firstKey= req->firstKey; + nKeys= req->nKeys; + nAtoms+= nKeys; /* technically not atoms, but 4 bytes wide */ + } + else which&= ~XkbKeyNamesMask; + + if (which&XkbKeyAliasesMask) { + nKA= ((names->key_aliases!=NULL)?names->num_key_aliases:0); + if (nKA>0) { + req->nKeyAliases= nKA; + nAtoms+= nKA*2; /* not atoms, but 8 bytes on the wire */ + } + else { + which&= ~XkbKeyAliasesMask; + req->nKeyAliases = 0; + } + } + else req->nKeyAliases= 0; + + if (which&XkbRGNamesMask) { + nRG= names->num_rg; + if (nRG>0) + nAtoms+= nRG; + else which&= ~XkbRGNamesMask; + } + + req->which= which; + req->nRadioGroups= nRG; + req->length+= (nAtoms*4)/4; + + if (which&XkbKeycodesNameMask) + Data32(dpy,(long *)&names->keycodes,4); + if (which&XkbGeometryNameMask) + Data32(dpy,(long *)&names->geometry,4); + if (which&XkbSymbolsNameMask) + Data32(dpy,(long *)&names->symbols,4); + if (which&XkbPhysSymbolsNameMask) + Data32(dpy,(long *)&names->phys_symbols,4); + if (which&XkbTypesNameMask) + Data32(dpy,(long *)&names->types,4); + if (which&XkbCompatNameMask) + Data32(dpy,(long *)&names->compat,4); + if (which&XkbKeyTypeNamesMask) { + register int i; + register XkbKeyTypePtr type; + type= &xkb->map->types[firstType]; + for (i=0;i<nTypes;i++,type++) { + Data32(dpy,(long *)&type->name,4); + } + } + if (which&XkbKTLevelNamesMask) { + XkbKeyTypePtr type; + int i; + char *tmp; + + BufAlloc(char *,tmp,XkbPaddedSize(nLvlTypes)); + type = &xkb->map->types[firstLvlType]; + for (i=0;i<nLvlTypes;i++,type++) { + *tmp++ = type->num_levels; + } + type = &xkb->map->types[firstLvlType]; + for (i=0;i<nLvlTypes;i++,type++) { + if (type->level_names!=NULL) + Data32(dpy,(long *)type->level_names,type->num_levels*4); + } + } + if (which&XkbIndicatorNamesMask) + _XkbCopyAtoms(dpy,names->indicators,leds,XkbNumIndicators); + if (which&XkbVirtualModNamesMask) + _XkbCopyAtoms(dpy,names->vmods,vmods,XkbNumVirtualMods); + if (which&XkbGroupNamesMask) + _XkbCopyAtoms(dpy,names->groups,groups,XkbNumKbdGroups); + if (which&XkbKeyNamesMask) { +#ifdef WORD64 + char *tmp; + register int i; + BufAlloc(char *,tmp,nKeys*XkbKeyNameLength); + for (i=0;i<nKeys;i++,tmp+= XkbKeyNameLength) { + tmp[0]= names->keys[firstKey+i].name[0]; + tmp[1]= names->keys[firstKey+i].name[1]; + tmp[2]= names->keys[firstKey+i].name[2]; + tmp[3]= names->keys[firstKey+i].name[3]; + } +#else + Data(dpy,(char *)&names->keys[firstKey],nKeys*XkbKeyNameLength); +#endif + } + if (which&XkbKeyAliasesMask) { +#ifdef WORD64 + char *tmp; + register int i; + BufAlloc(char *,tmp,nKA*XkbKeyNameLength*2); + for (i=0;i<nKeys;i++,tmp+= 2*XkbKeyNameLength) { + tmp[0]= names->key_aliases[i].real[0]; + tmp[1]= names->key_aliases[i].real[1]; + tmp[2]= names->key_aliases[i].real[2]; + tmp[3]= names->key_aliases[i].real[3]; + tmp[4]= names->key_aliases[i].alias[0]; + tmp[5]= names->key_aliases[i].alias[1]; + tmp[6]= names->key_aliases[i].alias[2]; + tmp[7]= names->key_aliases[i].alias[3]; + } +#else + Data(dpy,(char *)names->key_aliases,nKA*XkbKeyNameLength*2); +#endif + } + if (which&XkbRGNamesMask) { + Data32(dpy,(long *)names->radio_groups,nRG*4); + } + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + +Bool +#if NeedFunctionPrototypes +XkbChangeNames(Display *dpy,XkbDescPtr xkb,XkbNameChangesPtr changes) +#else +XkbChangeNames(dpy,xkb,changes) + Display * dpy; + XkbDescPtr xkb; + XkbNameChangesPtr changes; +#endif +{ + register xkbSetNamesReq *req; + int nLvlNames; + XkbInfoPtr xkbi; + XkbNamesPtr names; + unsigned which,firstType,nTypes; + unsigned firstLvlType,nLvlTypes; + int nVMods,nLEDs,nRG,nKA,nGroups; + int nKeys,firstKey,nAtoms; + CARD32 leds,vmods,groups; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) + return False; + if ((!xkb)||(!xkb->names)||(!changes)) + return False; + which= changes->changed; + firstType= changes->first_type; + nTypes= changes->num_types; + firstLvlType= changes->first_lvl;; + nLvlTypes= changes->num_lvls; + if (which&XkbKeyTypeNamesMask) { + if (nTypes<1) + which&= ~XkbKeyTypeNamesMask; + else if (firstType<=XkbLastRequiredType) { + int adjust; + adjust= XkbLastRequiredType-firstType+1; + firstType+= adjust; + nTypes-= adjust; + if (nTypes<1) + which&= ~XkbKeyTypeNamesMask; + } + } + else firstType= nTypes= 0; + + if (which&XkbKTLevelNamesMask) { + if (nLvlTypes<1) + which&= ~XkbKTLevelNamesMask; + } + else firstLvlType= nLvlTypes= 0; + + names= xkb->names; + if (which&(XkbKTLevelNamesMask|XkbKeyTypeNamesMask)) { + register int i; + XkbKeyTypePtr type; + if((xkb->map==NULL)||(xkb->map->types==NULL)||(nTypes==0)|| + (firstType+nTypes>xkb->map->num_types)|| + (firstLvlType+nLvlTypes>xkb->map->num_types)) + return False; + if (which&XkbKTLevelNamesMask) { + type= &xkb->map->types[firstLvlType]; + for (i=nLvlNames=0;i<nLvlTypes;i++,type++) { + if (type->level_names!=NULL) + nLvlNames+= type->num_levels; + } + } + } + + if (changes->num_keys<1) + which&= ~XkbKeyNamesMask; + if ((which&XkbKeyNamesMask)==0) + changes->first_key= changes->num_keys= 0; + else if ((changes->first_key<xkb->min_key_code)|| + (changes->first_key+changes->num_keys>xkb->max_key_code)) { + return False; + } + + if ((which&XkbVirtualModNamesMask)==0) + changes->changed_vmods= 0; + else if (changes->changed_vmods==0) + which&= ~XkbVirtualModNamesMask; + + if ((which&XkbIndicatorNamesMask)==0) + changes->changed_indicators= 0; + else if (changes->changed_indicators==0) + which&= ~XkbIndicatorNamesMask; + + if ((which&XkbGroupNamesMask)==0) + changes->changed_groups= 0; + else if (changes->changed_groups==0) + which&= ~XkbGroupNamesMask; + + nVMods= nLEDs= nRG= nKA= nAtoms= nGroups= 0; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbSetNames, req); + req->reqType = xkbi->codes->major_opcode; + req->xkbReqType = X_kbSetNames; + req->deviceSpec = xkb->device_spec; + req->firstType = firstType; + req->nTypes = nTypes; + req->firstKey = changes->first_key; + req->nKeys = changes->num_keys; + + if (which&XkbKeycodesNameMask) + nAtoms++; + if (which&XkbGeometryNameMask) + nAtoms++; + if (which&XkbSymbolsNameMask) + nAtoms++; + if (which&XkbPhysSymbolsNameMask) + nAtoms++; + if (which&XkbTypesNameMask) + nAtoms++; + if (which&XkbCompatNameMask) + nAtoms++; + if (which&XkbKeyTypeNamesMask) + nAtoms+= nTypes; + if (which&XkbKTLevelNamesMask) { + req->firstKTLevel= firstLvlType; + req->nKTLevels= nLvlTypes; + req->length+= XkbPaddedSize(nLvlTypes)/4; /* room for group widths */ + nAtoms+= nLvlNames; + } + else req->firstKTLevel= req->nKTLevels= 0; + + if (which&XkbIndicatorNamesMask) { + leds= req->indicators= (CARD32)changes->changed_indicators; + nLEDs= _XkbCountBits(XkbNumIndicators,changes->changed_indicators); + if (nLEDs>0) + nAtoms+= nLEDs; + else which&= ~XkbIndicatorNamesMask; + } + else req->indicators= 0; + + if (which&XkbVirtualModNamesMask) { + vmods= req->virtualMods= changes->changed_vmods; + nVMods= _XkbCountBits(XkbNumVirtualMods, + (unsigned long)changes->changed_vmods); + if (nVMods>0) + nAtoms+= nVMods; + else which&= ~XkbVirtualModNamesMask; + } + else req->virtualMods= 0; + + if (which&XkbGroupNamesMask) { + groups= req->groupNames= changes->changed_groups; + nGroups= _XkbCountBits(XkbNumKbdGroups, + (unsigned long)changes->changed_groups); + if (nGroups>0) + nAtoms+= nGroups; + else which&= ~XkbGroupNamesMask; + } + else req->groupNames= 0; + + if ((which&XkbKeyNamesMask)&&(names->keys!=NULL)) { + firstKey= req->firstKey; + nKeys= req->nKeys; + nAtoms+= nKeys; /* technically not atoms, but 4 bytes wide */ + } + else which&= ~XkbKeyNamesMask; + + if (which&XkbKeyAliasesMask) { + nKA= ((names->key_aliases!=NULL)?names->num_key_aliases:0); + if (nKA>0) + nAtoms+= nKA*2; /* not atoms, but 8 bytes on the wire */ + else which&= ~XkbKeyAliasesMask; + } + + if (which&XkbRGNamesMask) { + nRG= names->num_rg; + if (nRG>0) + nAtoms+= nRG; + else which&= ~XkbRGNamesMask; + } + + req->which= which; + req->nRadioGroups= nRG; + req->length+= (nAtoms*4)/4; + + if (which&XkbKeycodesNameMask) + Data32(dpy,(long *)&names->keycodes,4); + if (which&XkbGeometryNameMask) + Data32(dpy,(long *)&names->geometry,4); + if (which&XkbSymbolsNameMask) + Data32(dpy,(long *)&names->symbols,4); + if (which&XkbPhysSymbolsNameMask) + Data32(dpy,(long *)&names->phys_symbols,4); + if (which&XkbTypesNameMask) + Data32(dpy,(long *)&names->types,4); + if (which&XkbCompatNameMask) + Data32(dpy,(long *)&names->compat,4); + if (which&XkbKeyTypeNamesMask) { + register int i; + register XkbKeyTypePtr type; + type= &xkb->map->types[firstType]; + for (i=0;i<nTypes;i++,type++) { + Data32(dpy,(long *)&type->name,4); + } + } + if (which&XkbKTLevelNamesMask) { + XkbKeyTypePtr type; + int i; + char *tmp; + + BufAlloc(char *,tmp,XkbPaddedSize(nLvlTypes)); + type = &xkb->map->types[firstLvlType]; + for (i=0;i<nLvlTypes;i++,type++) { + *tmp++ = type->num_levels; + } + type = &xkb->map->types[firstLvlType]; + for (i=0;i<nLvlTypes;i++,type++) { + if (type->level_names!=NULL) + Data32(dpy,(long *)type->level_names,type->num_levels*4); + } + } + if (which&XkbIndicatorNamesMask) + _XkbCopyAtoms(dpy,names->indicators,leds,XkbNumIndicators); + if (which&XkbVirtualModNamesMask) + _XkbCopyAtoms(dpy,names->vmods,vmods,XkbNumVirtualMods); + if (which&XkbGroupNamesMask) + _XkbCopyAtoms(dpy,names->groups,groups,XkbNumKbdGroups); + if (which&XkbKeyNamesMask) { +#ifdef WORD64 + char *tmp; + register int i; + BufAlloc(char *,tmp,nKeys*4); + for (i=0;i<nKeys;i++,tmp+= 4) { + tmp[0]= names->keys[firstKey+i].name[0]; + tmp[1]= names->keys[firstKey+i].name[1]; + tmp[2]= names->keys[firstKey+i].name[2]; + tmp[3]= names->keys[firstKey+i].name[3]; + } +#else + Data(dpy,(char *)&names->keys[firstKey],nKeys*XkbKeyNameLength); +#endif + } + if (which&XkbKeyAliasesMask) { +#ifdef WORD64 + char *tmp; + register int i; + BufAlloc(char *,tmp,nKA*XkbKeyNameLength*2); + for (i=0;i<nKeys;i++,tmp+= 2*XkbKeyNameLength) { + tmp[0]= names->key_aliases[i].real[0]; + tmp[1]= names->key_aliases[i].real[1]; + tmp[2]= names->key_aliases[i].real[2]; + tmp[3]= names->key_aliases[i].real[3]; + tmp[4]= names->key_aliases[i].alias[0]; + tmp[5]= names->key_aliases[i].alias[1]; + tmp[6]= names->key_aliases[i].alias[2]; + tmp[7]= names->key_aliases[i].alias[3]; + } +#else + Data(dpy,(char *)names->key_aliases,nKA*XkbKeyNameLength*2); +#endif + } + if (which&XkbRGNamesMask) { + Data32(dpy,(long *)names->radio_groups,nRG*4); + } + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + +void +#if NeedFunctionPrototypes +XkbNoteNameChanges( XkbNameChangesPtr old, + XkbNamesNotifyEvent * new, + unsigned int wanted) +#else +XkbNoteNameChanges(old,new,wanted) + XkbNameChangesPtr old; + XkbNamesNotifyEvent * new; + unsigned int wanted; +#endif +{ +int first,last,old_last,new_last; + + wanted&= new->changed; + if ((old==NULL)||(new==NULL)||(wanted==0)) + return; + if (wanted&XkbKeyTypeNamesMask) { + if (old->changed&XkbKeyTypeNamesMask) { + new_last= (new->first_type+new->num_types-1); + old_last= (old->first_type+old->num_types-1); + + if (new->first_type<old->first_type) + first= new->first_type; + else first= old->first_type; + + if (old_last>new_last) + last= old_last; + else last= new_last; + + old->first_type= first; + old->num_types= (last-first)+1; + } + else { + old->first_type= new->first_type; + old->num_types= new->num_types; + } + } + if (wanted&XkbKTLevelNamesMask) { + if (old->changed&XkbKTLevelNamesMask) { + new_last= (new->first_lvl+new->num_lvls-1); + old_last= (old->first_lvl+old->num_lvls-1); + + if (new->first_lvl<old->first_lvl) + first= new->first_lvl; + else first= old->first_lvl; + + if (old_last>new_last) + last= old_last; + else last= new_last; + + old->first_lvl= first; + old->num_lvls= (last-first)+1; + } + else { + old->first_lvl= new->first_lvl; + old->num_lvls= new->num_lvls; + } + } + if (wanted&XkbIndicatorNamesMask) { + if (old->changed&XkbIndicatorNamesMask) + old->changed_indicators|= new->changed_indicators; + else old->changed_indicators= new->changed_indicators; + } + if (wanted&XkbKeyNamesMask) { + if (old->changed&XkbKeyNamesMask) { + new_last= (new->first_key+new->num_keys-1); + old_last= (old->first_key+old->num_keys-1); + + first= old->first_key; + + if (new->first_key<old->first_key) + first= new->first_key; + if (old_last>new_last) + new_last= old_last; + + old->first_key= first; + old->num_keys= (new_last-first)+1; + } + else { + old->first_key= new->first_key; + old->num_keys= new->num_keys; + } + } + if (wanted&XkbVirtualModNamesMask) { + if (old->changed&XkbVirtualModNamesMask) + old->changed_vmods|= new->changed_vmods; + else old->changed_vmods= new->changed_vmods; + } + if (wanted&XkbGroupNamesMask) { + if (old->changed&XkbGroupNamesMask) + old->changed_groups|= new->changed_groups; + else old->changed_groups= new->changed_groups; + } + if (wanted&XkbRGNamesMask) + old->num_rg= new->num_radio_groups; + if (wanted&XkbKeyAliasesMask) + old->num_aliases= new->num_aliases; + old->changed|= wanted; + return; +} diff --git a/src/xkb/XKBRdBuf.c b/src/xkb/XKBRdBuf.c new file mode 100644 index 00000000..11a9ba71 --- /dev/null +++ b/src/xkb/XKBRdBuf.c @@ -0,0 +1,322 @@ +/* $Xorg: XKBRdBuf.c,v 1.3 2000/08/17 19:45:02 cpqbld Exp $ */ +/************************************************************ +Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc. + +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 Silicon Graphics not be +used in advertising or publicity pertaining to distribution +of the software without specific prior written permission. +Silicon Graphics makes no representation about the suitability +of this software for any purpose. It is provided "as is" +without any express or implied warranty. + +SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS +SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON +GRAPHICS 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. + +********************************************************/ + +#include <stdio.h> +#define NEED_REPLIES +#define NEED_EVENTS +#include "Xlibint.h" +#include "XKBlibint.h" +#include <X11/extensions/XKBproto.h> + +/***====================================================================***/ + +int +#if NeedFunctionPrototypes +_XkbInitReadBuffer(Display *dpy,XkbReadBufferPtr buf,int size) +#else +_XkbInitReadBuffer(dpy,buf,size) + Display *dpy; + XkbReadBufferPtr buf; + int size; +#endif +{ + if ((dpy!=NULL) && (buf!=NULL) && (size>0)) { + buf->error= 0; + buf->size= size; + buf->start= buf->data= _XkbAlloc(size); + if (buf->start) { + _XRead(dpy, buf->start, size); + return 1; + } + } + return 0; +} + +#define _XkbReadBufferDataLeft(b) (((b)->size)-((b)->data-(b)->start)) + +int +#if NeedFunctionPrototypes +_XkbSkipReadBufferData(XkbReadBufferPtr from,int size) +#else +_XkbSkipReadBufferData(from,size) + XkbReadBufferPtr from; + int size; +#endif +{ + if (size==0) + return 1; + if ((from==NULL)||(from->error)||(size<1)|| + (_XkbReadBufferDataLeft(from)<size)) + return 0; + from->data+= size; + return 1; +} + +int +#if NeedFunctionPrototypes +_XkbCopyFromReadBuffer(XkbReadBufferPtr from,char *to,int size) +#else +_XkbCopyFromReadBuffer(from,to,size) + XkbReadBufferPtr from; + char *to; + int size; +#endif +{ + if (size==0) + return 1; + if ((from==NULL)||(from->error)||(to==NULL)||(size<1)|| + (_XkbReadBufferDataLeft(from)<size)) + return 0; + memcpy(to,from->data,size); + from->data+= size; + return 1; +} + +#ifdef XKB_FORCE_INT_KEYSYM +int +#if NeedFunctionPrototypes +_XkbReadCopyKeySyms(int *wire,KeySym *to,int num_words) +#else +_XkbReadCopyKeySyms(wire,to,num_words) + int * wire; + KeySym * to; + int num_words; +#endif +{ + while (num_words-->0) { + *to++= *wire++; + } + return 1; +} + +int +#if NeedFunctionPrototypes +_XkbReadBufferCopyKeySyms(XkbReadBufferPtr from,KeySym *to,int num_words) +#else +_XkbReadBufferCopyKeySyms(from,to,num_words) + XkbReadBufferPtr from; + KeySym * to; + int num_words; +#endif +{ + if ((unsigned)(num_words*4)>_XkbReadBufferDataLeft(from)) + return 0; + _XkbReadCopyKeySyms((int *)from->data,to,num_words); + from->data+= (4*num_words); + return True; +} + +int +#if NeedFunctionPrototypes +_XkbWriteCopyKeySyms (register KeySym *from,CARD32 *to,int len) +#else +_XkbWriteCopyKeySyms (from,to,len) + register KeySym * from; + CARD32 * to; + int len; +#endif +{ + + while (len-->0) { + *to++= (CARD32)*from++; + } + return True; +} +#endif + +#ifdef LONG64 +int +#if NeedFunctionPrototypes +_XkbReadCopyData32(int *wire,long *to,int num_words) +#else +_XkbReadCopyData32(wire,to,num_words) + int * wire; + long * to; + int num_words; +#endif +{ + while (num_words-->0) { + *to++= *wire++; + } + return 1; +} +#endif +#ifdef WORD64 +int +#if NeedFunctionPrototypes +_XkbReadCopyData32(int *from,long *lp,int num_words) +#else +_XkbReadCopyData32(from,lp,num_words) + int * from; + long * lp; + int num_words; +#endif +{ +long *lpack; +long mask32 = 0x00000000ffffffff; +long maskw, i, bits; + + lpack = (long *)from; + bits = 32; + + for (i=0;i<num_words;i++) { + maskw = mask32 << bits; + *lp++ = (*lpack & maskw) >> bits; + bits = bits ^ 32; + if (bits) + lpack++; + } + return 1; +} +#endif + +#if defined(LONG64) || defined(WORD64) +int +#if NeedFunctionPrototypes +_XkbReadBufferCopy32(XkbReadBufferPtr from,long *to,int num_words) +#else +_XkbReadBufferCopy32(from,to,num_words) + XkbReadBufferPtr from; + long * to; + int num_words; +#endif +{ + if ((unsigned)(num_words*4)>_XkbReadBufferDataLeft(from)) + return 0; + _XkbReadCopyData32((int *)from->data,to,num_words); + from->data+= (4*num_words); + return True; +} +#endif + +#ifdef LONG64 +int +#if NeedFunctionPrototypes +_XkbWriteCopyData32 (register unsigned long *from,CARD32 *to,int len) +#else +_XkbWriteCopyData32 (from,to,len) + register unsigned long * from; + CARD32 * to; + int len; +#endif +{ + + while (len-->0) { + *to++= (CARD32)*from++; + } + return True; +} +#endif /* LONG64 */ + +#ifdef WORD64 +_XkbWriteCopyData32 Not Implemented Yet for sizeof(int)==8 +#endif + +char * +#if NeedFunctionPrototypes +_XkbPeekAtReadBuffer(XkbReadBufferPtr from,int size) +#else +_XkbPeekAtReadBuffer(from,size) + XkbReadBufferPtr from; + int size; +#endif +{ + if ((from==NULL)||(from->error)||(size<1)|| + (_XkbReadBufferDataLeft(from)<size)) + return 0; + return from->data; +} + +char * +#if NeedFunctionPrototypes +_XkbGetReadBufferPtr(XkbReadBufferPtr from,int size) +#else +_XkbGetReadBufferPtr(from,size) + XkbReadBufferPtr from; + int size; +#endif +{ +char *ptr; + if ((from==NULL)||(from->error)||(size<1)|| + (_XkbReadBufferDataLeft(from)<size)) + return 0; + ptr= from->data; + from->data+= size; + return ptr; +} + + +int +#if NeedFunctionPrototypes +_XkbFreeReadBuffer(XkbReadBufferPtr buf) +#else +_XkbFreeReadBuffer(buf) + XkbReadBufferPtr buf; +#endif +{ + if ((buf!=NULL) && (buf->start!=NULL)) { + int left; + left= (int)_XkbReadBufferDataLeft(buf); + if (buf->start!=NULL) + Xfree(buf->start); + buf->size= 0; + buf->start= buf->data= NULL; + return left; + } + return 0; +} + +Bool +#if NeedFunctionPrototypes +_XkbGetReadBufferCountedString(XkbReadBufferPtr buf,char **rtrn) +#else +_XkbGetReadBufferCountedString(buf,rtrn) + XkbReadBufferPtr buf; + char ** rtrn; +#endif +{ +CARD16 len,*pLen; +int left; +char * str; + + if ((buf==NULL)||(buf->error)||((left=(int)_XkbReadBufferDataLeft(buf))<4)) + return False; + pLen= (CARD16 *)buf->data; + len= *pLen; + if (len>0) { + if (XkbPaddedSize(len+2)>left) + return False; + str= _XkbAlloc(len+1); + if (str) { + memcpy(str,&buf->data[2],len); + str[len]= '\0'; + } + } + buf->data+= XkbPaddedSize(len+2); + *rtrn= str; + return True; +} diff --git a/src/xkb/XKBSetGeom.c b/src/xkb/XKBSetGeom.c new file mode 100644 index 00000000..72d7f3d7 --- /dev/null +++ b/src/xkb/XKBSetGeom.c @@ -0,0 +1,561 @@ +/* $Xorg: XKBSetGeom.c,v 1.3 2000/08/17 19:45:03 cpqbld Exp $ */ +/************************************************************ +Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc. + +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 Silicon Graphics not be +used in advertising or publicity pertaining to distribution +of the software without specific prior written permission. +Silicon Graphics makes no representation about the suitability +of this software for any purpose. It is provided "as is" +without any express or implied warranty. + +SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS +SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON +GRAPHICS 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 DEBUG +#include <stdio.h> +#endif + +#define NEED_EVENTS +#define NEED_REPLIES +#include "Xlibint.h" +#include "XKBlibint.h" +#include <X11/extensions/XKBgeom.h> +#include <X11/extensions/XKBproto.h> + +#ifndef MINSHORT +#define MINSHORT -32768 +#endif +#ifndef MAXSHORT +#define MAXSHORT 32767 +#endif + +/***====================================================================***/ + +#define _SizeCountedString(s) ((s)?XkbPaddedSize(2+strlen(s)):4) + +static char * +#if NeedFunctionPrototypes +_WriteCountedString(char *wire,char *str) +#else +_WriteCountedString(wire,str) + char * wire; + char * str; +#endif +{ +CARD16 len,*pLen; + + len= (str?strlen(str):0); + pLen= (CARD16 *)wire; + *pLen= len; + if (len && str) + memcpy(&wire[2],str,len); + wire+= XkbPaddedSize(len+2); + return wire; +} + +static int +#if NeedFunctionPrototypes +_SizeGeomProperties(XkbGeometryPtr geom) +#else +_SizeGeomProperties(geom) + XkbGeometryPtr geom; +#endif +{ +register int i,size; +XkbPropertyPtr prop; + + for (size=i=0,prop=geom->properties;i<geom->num_properties;i++,prop++) { + size+= _SizeCountedString(prop->name); + size+= _SizeCountedString(prop->value); + } + return size; +} + +static int +#if NeedFunctionPrototypes +_SizeGeomColors(XkbGeometryPtr geom) +#else +_SizeGeomColors(geom) + XkbGeometryPtr geom; +#endif +{ +register int i,size; +register XkbColorPtr color; + + for (i=size=0,color=geom->colors;i<geom->num_colors;i++,color++) { + size+= _SizeCountedString(color->spec); + } + return size; +} + +static int +#if NeedFunctionPrototypes +_SizeGeomShapes(XkbGeometryPtr geom) +#else +_SizeGeomShapes(geom) + XkbGeometryPtr geom; +#endif +{ +register int i,size; +register XkbShapePtr shape; + + for (i=size=0,shape=geom->shapes;i<geom->num_shapes;i++,shape++) { + register int n; + register XkbOutlinePtr ol; + size+= SIZEOF(xkbShapeWireDesc); + for (n=0,ol=shape->outlines;n<shape->num_outlines;n++,ol++) { + size+= SIZEOF(xkbOutlineWireDesc); + size+= ol->num_points*SIZEOF(xkbPointWireDesc); + } + } + return size; +} + +static int +#if NeedFunctionPrototypes +_SizeGeomDoodads(int num_doodads,XkbDoodadPtr doodad) +#else +_SizeGeomDoodads(num_doodads,doodad) + int num_doodads; + XkbDoodadPtr doodad; +#endif +{ +register int i,size; + + for (i=size=0;i<num_doodads;i++,doodad++) { + size+= SIZEOF(xkbAnyDoodadWireDesc); + if (doodad->any.type==XkbTextDoodad) { + size+= _SizeCountedString(doodad->text.text); + size+= _SizeCountedString(doodad->text.font); + } + else if (doodad->any.type==XkbLogoDoodad) { + size+= _SizeCountedString(doodad->logo.logo_name); + } + } + return size; +} + +static int +#if NeedFunctionPrototypes +_SizeGeomSections(XkbGeometryPtr geom) +#else +_SizeGeomSections(geom) + XkbGeometryPtr geom; +#endif +{ +register int i,size; +XkbSectionPtr section; + + for (i=size=0,section=geom->sections;i<geom->num_sections;i++,section++) { + size+= SIZEOF(xkbSectionWireDesc); + if (section->rows) { + int r; + XkbRowPtr row; + for (r=0,row=section->rows;r<section->num_rows;row++,r++) { + size+= SIZEOF(xkbRowWireDesc); + size+= row->num_keys*SIZEOF(xkbKeyWireDesc); + } + } + if (section->doodads) + size+= _SizeGeomDoodads(section->num_doodads,section->doodads); + if (section->overlays) { + int o; + XkbOverlayPtr ol; + for (o=0,ol=section->overlays;o<section->num_overlays;o++,ol++) { + int r; + XkbOverlayRowPtr row; + size+= SIZEOF(xkbOverlayWireDesc); + for (r=0,row=ol->rows;r<ol->num_rows;r++,row++) { + size+= SIZEOF(xkbOverlayRowWireDesc); + size+= row->num_keys*SIZEOF(xkbOverlayKeyWireDesc); + } + } + } + } + return size; +} + +static int +#if NeedFunctionPrototypes +_SizeGeomKeyAliases(XkbGeometryPtr geom) +#else +_SizeGeomKeyAliases(geom) + XkbGeometryPtr geom; +#endif +{ + return geom->num_key_aliases*(2*XkbKeyNameLength); +} + +/***====================================================================***/ + +static char * +#if NeedFunctionPrototypes +_WriteGeomProperties(char *wire,XkbGeometryPtr geom) +#else +_WriteGeomProperties(wire,geom) + char * wire; + XkbGeometryPtr geom; +#endif +{ +register int i; +register XkbPropertyPtr prop; + + for (i=0,prop=geom->properties;i<geom->num_properties;i++,prop++) { + wire= _WriteCountedString(wire,prop->name); + wire= _WriteCountedString(wire,prop->value); + } + return wire; +} + +static char * +#if NeedFunctionPrototypes +_WriteGeomColors(char *wire,XkbGeometryPtr geom) +#else +_WriteGeomColors(wire,geom) + char * wire; + XkbGeometryPtr geom; +#endif +{ +register int i; +register XkbColorPtr color; + + for (i=0,color=geom->colors;i<geom->num_colors;i++,color++) { + wire= _WriteCountedString(wire,color->spec); + } + return wire; +} + +static char * +#if NeedFunctionPrototypes +_WriteGeomShapes(char *wire,XkbGeometryPtr geom) +#else +_WriteGeomShapes(wire,geom) + char * wire; + XkbGeometryPtr geom; +#endif +{ +int i; +XkbShapePtr shape; +xkbShapeWireDesc * shapeWire; + + for (i=0,shape=geom->shapes;i<geom->num_shapes;i++,shape++) { + register int o; + XkbOutlinePtr ol; + xkbOutlineWireDesc * olWire; + shapeWire= (xkbShapeWireDesc *)wire; + shapeWire->name= shape->name; + shapeWire->nOutlines= shape->num_outlines; + if (shape->primary!=NULL) + shapeWire->primaryNdx= XkbOutlineIndex(shape,shape->primary); + else shapeWire->primaryNdx= XkbNoShape; + if (shape->approx!=NULL) + shapeWire->approxNdx= XkbOutlineIndex(shape,shape->approx); + else shapeWire->approxNdx= XkbNoShape; + wire= (char *)&shapeWire[1]; + for (o=0,ol=shape->outlines;o<shape->num_outlines;o++,ol++) { + register int p; + XkbPointPtr pt; + xkbPointWireDesc * ptWire; + olWire= (xkbOutlineWireDesc *)wire; + olWire->nPoints= ol->num_points; + olWire->cornerRadius= ol->corner_radius; + wire= (char *)&olWire[1]; + ptWire= (xkbPointWireDesc *)wire; + for (p=0,pt=ol->points;p<ol->num_points;p++,pt++) { + ptWire[p].x= pt->x; + ptWire[p].y= pt->y; + } + wire= (char *)&ptWire[ol->num_points]; + } + } + return wire; +} + +static char * +#if NeedFunctionPrototypes +_WriteGeomDoodads(char *wire,int num_doodads,XkbDoodadPtr doodad) +#else +_WriteGeomDoodads(wire,num_doodads,doodad) + char * wire; + int num_doodads; + XkbDoodadPtr doodad; +#endif +{ +register int i; +xkbDoodadWireDesc * doodadWire; + + for (i=0;i<num_doodads;i++,doodad++) { + doodadWire= (xkbDoodadWireDesc *)wire; + wire= (char *)&doodadWire[1]; + bzero(doodadWire,SIZEOF(xkbDoodadWireDesc)); + doodadWire->any.name= doodad->any.name; + doodadWire->any.type= doodad->any.type; + doodadWire->any.priority= doodad->any.priority; + doodadWire->any.top= doodad->any.top; + doodadWire->any.left= doodad->any.left; + doodadWire->any.angle= doodad->any.angle; + switch (doodad->any.type) { + case XkbOutlineDoodad: + case XkbSolidDoodad: + doodadWire->shape.colorNdx= doodad->shape.color_ndx; + doodadWire->shape.shapeNdx= doodad->shape.shape_ndx; + break; + case XkbTextDoodad: + doodadWire->text.width= doodad->text.width; + doodadWire->text.height= doodad->text.height; + doodadWire->text.colorNdx= doodad->text.color_ndx; + wire= _WriteCountedString(wire,doodad->text.text); + wire= _WriteCountedString(wire,doodad->text.font); + break; + case XkbIndicatorDoodad: + doodadWire->indicator.shapeNdx= doodad->indicator.shape_ndx; + doodadWire->indicator.onColorNdx=doodad->indicator.on_color_ndx; + doodadWire->indicator.offColorNdx= + doodad->indicator.off_color_ndx; + break; + case XkbLogoDoodad: + doodadWire->logo.colorNdx= doodad->logo.color_ndx; + doodadWire->logo.shapeNdx= doodad->logo.shape_ndx; + wire= _WriteCountedString(wire,doodad->logo.logo_name); + break; + default: + break; + } + } + return wire; +} + +static char * +#if NeedFunctionPrototypes +_WriteGeomOverlay(char *wire,XkbOverlayPtr ol) +#else +_WriteGeomOverlay(wire,ol) + char * wire; + XkbOverlayPtr ol; +#endif +{ +register int r; +XkbOverlayRowPtr row; +xkbOverlayWireDesc * olWire; + + olWire= (xkbOverlayWireDesc *)wire; + olWire->name= ol->name; + olWire->nRows= ol->num_rows; + wire= (char *)&olWire[1]; + for (r=0,row=ol->rows;r<ol->num_rows;r++,row++) { + unsigned int k; + XkbOverlayKeyPtr key; + xkbOverlayRowWireDesc * rowWire; + rowWire= (xkbOverlayRowWireDesc *)wire; + rowWire->rowUnder= row->row_under; + rowWire->nKeys= row->num_keys; + wire= (char *)&rowWire[1]; + for (k=0,key=row->keys;k<row->num_keys;k++,key++) { + xkbOverlayKeyWireDesc * keyWire; + keyWire= (xkbOverlayKeyWireDesc *)wire; + memcpy(keyWire->over,key->over.name,XkbKeyNameLength); + memcpy(keyWire->under,key->under.name,XkbKeyNameLength); + wire= (char *)&keyWire[1]; + } + } + return wire; +} + +static char * +#if NeedFunctionPrototypes +_WriteGeomSections(char *wire,XkbGeometryPtr geom) +#else +_WriteGeomSections(wire,geom) + char * wire; + XkbGeometryPtr geom; +#endif +{ +register int i; +XkbSectionPtr section; +xkbSectionWireDesc * sectionWire; + + for (i=0,section=geom->sections;i<geom->num_sections;i++,section++) { + sectionWire= (xkbSectionWireDesc *)wire; + sectionWire->name= section->name; + sectionWire->top= section->top; + sectionWire->left= section->left; + sectionWire->width= section->width; + sectionWire->height= section->height; + sectionWire->angle= section->angle; + sectionWire->priority= section->priority; + sectionWire->nRows= section->num_rows; + sectionWire->nDoodads= section->num_doodads; + sectionWire->nOverlays= section->num_overlays; + sectionWire->pad= 0; + wire= (char *)§ionWire[1]; + if (section->rows) { + int r; + XkbRowPtr row; + xkbRowWireDesc * rowWire; + for (r=0,row=section->rows;r<section->num_rows;r++,row++) { + rowWire= (xkbRowWireDesc *)wire; + rowWire->top= row->top; + rowWire->left= row->left; + rowWire->nKeys= row->num_keys; + rowWire->vertical= row->vertical; + rowWire->pad= 0; + wire= (char *)&rowWire[1]; + if (row->keys) { + int k; + XkbKeyPtr key; + xkbKeyWireDesc * keyWire; + keyWire= (xkbKeyWireDesc *)wire; + for (k=0,key=row->keys;k<row->num_keys;k++,key++) { + memcpy(keyWire[k].name,key->name.name,XkbKeyNameLength); + keyWire[k].gap= key->gap; + keyWire[k].shapeNdx= key->shape_ndx; + keyWire[k].colorNdx= key->color_ndx; + } + wire= (char *)&keyWire[row->num_keys]; + } + } + } + if (section->doodads) { + wire= _WriteGeomDoodads(wire, + section->num_doodads,section->doodads); + } + if (section->overlays) { + register int o; + for (o=0;o<section->num_overlays;o++) { + wire= _WriteGeomOverlay(wire,§ion->overlays[o]); + } + } + } + return wire; +} + +static char * +#if NeedFunctionPrototypes +_WriteGeomKeyAliases(char *wire,XkbGeometryPtr geom) +#else +_WriteGeomKeyAliases(wire,geom) + char * wire; + XkbGeometryPtr geom; +#endif +{ +register int sz; + + sz= geom->num_key_aliases*(XkbKeyNameLength*2); + if (sz>0) { + memcpy(wire,(char *)geom->key_aliases,sz); + wire+= sz; + } + return wire; +} + +/***====================================================================***/ + +static Status +#if NeedFunctionPrototypes +_SendSetGeometry(Display *dpy,XkbGeometryPtr geom,xkbSetGeometryReq *req) +#else +_SendSetGeometry(dpy,geom,req) + Display * dpy; + XkbGeometryPtr geom; + xkbSetGeometryReq * req; +#endif +{ +xkbSetGeometryReq tmp; +int sz; +char * wire,*tbuf; + + sz= 0; + sz+= _SizeCountedString(geom->label_font); + sz+= _SizeGeomProperties(geom); + sz+= _SizeGeomColors(geom); + sz+= _SizeGeomShapes(geom); + sz+= _SizeGeomSections(geom); + sz+= _SizeGeomDoodads(geom->num_doodads,geom->doodads); + sz+= _SizeGeomKeyAliases(geom); + req->length+= (sz/4); + tmp= *req; + if (sz<BUFSIZE) { + BufAlloc(char *,wire,sz); + tbuf= NULL; + } + else { + tbuf= _XAllocTemp(dpy,sz); + if (!tbuf) + return BadAlloc; + wire= tbuf; + } + wire= _WriteCountedString(wire,geom->label_font); + if (geom->num_properties>0) + wire= _WriteGeomProperties(wire,geom); + if (geom->num_colors>0) + wire= _WriteGeomColors(wire,geom); + if (geom->num_shapes>0) + wire= _WriteGeomShapes(wire,geom); + if (geom->num_sections>0) + wire= _WriteGeomSections(wire,geom); + if (geom->num_doodads>0) + wire= _WriteGeomDoodads(wire,geom->num_doodads,geom->doodads); + if (geom->num_key_aliases>0) + wire= _WriteGeomKeyAliases(wire,geom); + if (tbuf!=NULL) { + Data(dpy,tbuf,sz); + _XFreeTemp(dpy,tbuf,sz); + } + return Success; +} + +/***====================================================================***/ + +Status +#if NeedFunctionPrototypes +XkbSetGeometry(Display *dpy,unsigned deviceSpec,XkbGeometryPtr geom) +#else +XkbSetGeometry(dpy,deviceSpec,geom) + Display * dpy; + unsigned deviceSpec; + XkbGeometryPtr geom; +#endif +{ +xkbSetGeometryReq *req; +Status ret; + + if ( (!geom) || (dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) + return BadAccess; + + GetReq(kbSetGeometry, req); + req->reqType = dpy->xkb_info->codes->major_opcode; + req->xkbReqType = X_kbSetGeometry; + req->deviceSpec = deviceSpec; + req->nShapes= geom->num_shapes; + req->nSections= geom->num_sections; + req->name= geom->name; + req->widthMM= geom->width_mm; + req->heightMM= geom->height_mm; + req->nProperties= geom->num_properties; + req->nColors= geom->num_colors; + req->nDoodads= geom->num_doodads; + req->nKeyAliases= geom->num_key_aliases; + req->baseColorNdx= (geom->base_color-geom->colors); + req->labelColorNdx= (geom->label_color-geom->colors); + + ret = _SendSetGeometry(dpy,geom,req); + UnlockDisplay(dpy); + SyncHandle(); + return ret; +} + diff --git a/src/xkb/XKBSetMap.c b/src/xkb/XKBSetMap.c new file mode 100644 index 00000000..f7b99bde --- /dev/null +++ b/src/xkb/XKBSetMap.c @@ -0,0 +1,716 @@ +/* $Xorg: XKBSetMap.c,v 1.4 2000/08/17 19:45:03 cpqbld Exp $ */ +/************************************************************ +Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc. + +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 Silicon Graphics not be +used in advertising or publicity pertaining to distribution +of the software without specific prior written permission. +Silicon Graphics makes no representation about the suitability +of this software for any purpose. It is provided "as is" +without any express or implied warranty. + +SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS +SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON +GRAPHICS 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. + +********************************************************/ + +#include <stdio.h> +#define NEED_REPLIES +#define NEED_EVENTS +#include "Xlibint.h" +#include <X11/extensions/XKBproto.h> +#include "XKBlibint.h" + +static int +#if NeedFunctionPrototypes +_XkbSizeKeyTypes(XkbDescPtr xkb,xkbSetMapReq *req) +#else +_XkbSizeKeyTypes(xkb,req) + XkbDescPtr xkb; + xkbSetMapReq * req; +#endif +{ + XkbKeyTypePtr map; + int i,len; + + if (((req->present&XkbKeyTypesMask)==0)||(req->nTypes==0)) { + req->present&= ~XkbKeyTypesMask; + req->firstType= req->nTypes= 0; + return 0; + } + len= 0; + map= &xkb->map->types[req->firstType]; + for (i=0;i<req->nTypes;i++,map++){ + len+= SIZEOF(xkbKeyTypeWireDesc); + len+= map->map_count*SIZEOF(xkbKTSetMapEntryWireDesc); + if (map->preserve) + len+= map->map_count*SIZEOF(xkbModsWireDesc); + } + return len; +} + +static void +#if NeedFunctionPrototypes +_XkbWriteKeyTypes(Display *dpy,XkbDescPtr xkb,xkbSetMapReq *req) +#else +_XkbWriteKeyTypes(dpy,xkb,req) + Display * dpy; + XkbDescPtr xkb; + xkbSetMapReq * req; +#endif +{ + char * buf; + XkbKeyTypePtr type; + int i,n,sz; + xkbKeyTypeWireDesc *desc; + + if ((req->present&XkbKeyTypesMask)==0) + return; + type= &xkb->map->types[req->firstType]; + for (i=0;i<req->nTypes;i++,type++) { + sz= SIZEOF(xkbKeyTypeWireDesc); + sz+= type->map_count*SIZEOF(xkbKTSetMapEntryWireDesc); + if (type->preserve) + sz+= type->map_count*SIZEOF(xkbModsWireDesc); + BufAlloc(xkbKeyTypeWireDesc *,desc,sz); + desc->mask = type->mods.mask; + desc->realMods = type->mods.real_mods; + desc->virtualMods = type->mods.vmods; + desc->numLevels = type->num_levels; + desc->nMapEntries = type->map_count; + desc->preserve = (type->preserve!=NULL); + buf= (char *)&desc[1]; + if (desc->nMapEntries>0) { + xkbKTSetMapEntryWireDesc *wire; + wire= (xkbKTSetMapEntryWireDesc *)buf; + for (n=0;n<type->map_count;n++,wire++) { + wire->level= type->map[n].level; + wire->realMods= type->map[n].mods.real_mods; + wire->virtualMods= type->map[n].mods.vmods; + } + buf= (char *)wire; + if (type->preserve) { + xkbModsWireDesc *pwire; + pwire= (xkbModsWireDesc *)buf; + for (n=0;n<type->map_count;n++,pwire++) { + pwire->realMods= type->preserve[n].real_mods; + pwire->virtualMods= type->preserve[n].vmods; + } + } + } + } + return; +} + +static int +#if NeedFunctionPrototypes +_XkbSizeKeySyms(XkbDescPtr xkb,xkbSetMapReq *req) +#else +_XkbSizeKeySyms(xkb,req) + XkbDescPtr xkb; + xkbSetMapReq * req; +#endif +{ + int i,len; + unsigned nSyms; + + if (((req->present&XkbKeySymsMask)==0)||(req->nKeySyms==0)) { + req->present&= ~XkbKeySymsMask; + req->firstKeySym= req->nKeySyms= 0; + req->totalSyms= 0; + return 0; + } + len= (int)(req->nKeySyms*sizeof(XkbSymMapRec)); + for (i=nSyms=0;i<req->nKeySyms;i++) { + nSyms+= XkbKeyNumSyms(xkb,i+req->firstKeySym); + } + len+= nSyms*sizeof(CARD32); + req->totalSyms= nSyms; + return len; +} + +static void +#if NeedFunctionPrototypes +_XkbWriteKeySyms(Display *dpy,XkbDescPtr xkb,xkbSetMapReq *req) +#else +_XkbWriteKeySyms(dpy,xkb,req) + Display * dpy; + XkbDescPtr xkb; + xkbSetMapReq * req; +#endif +{ +register KeySym * pSym; +CARD32 * outSym; +XkbSymMapPtr symMap; +xkbSymMapWireDesc *desc; +register int i; + + if ((req->present&XkbKeySymsMask)==0) + return; + symMap = &xkb->map->key_sym_map[req->firstKeySym]; + for (i=0;i<req->nKeySyms;i++,symMap++) { + BufAlloc(xkbSymMapWireDesc *,desc, + SIZEOF(xkbSymMapWireDesc)+ + (XkbKeyNumSyms(xkb,i+req->firstKeySym)*sizeof(CARD32))); + desc->ktIndex[0] = symMap->kt_index[0]; + desc->ktIndex[1] = symMap->kt_index[1]; + desc->ktIndex[2] = symMap->kt_index[2]; + desc->ktIndex[3] = symMap->kt_index[3]; + desc->groupInfo = symMap->group_info; + desc->width = symMap->width; + desc->nSyms = XkbKeyNumSyms(xkb,i+req->firstKeySym); + outSym = (CARD32 *)&desc[1]; + if (desc->nSyms>0) { + pSym = XkbKeySymsPtr(xkb,i+req->firstKeySym); + _XkbWriteCopyKeySyms(pSym,outSym,desc->nSyms); + } + } + return; +} + +static int +#if NeedFunctionPrototypes +_XkbSizeKeyActions(XkbDescPtr xkb,xkbSetMapReq *req) +#else +_XkbSizeKeyActions(xkb,req) + XkbDescPtr xkb; + xkbSetMapReq * req; +#endif +{ + int i,len,nActs; + + if (((req->present&XkbKeyActionsMask)==0)||(req->nKeyActs==0)) { + req->present&= ~XkbKeyActionsMask; + req->firstKeyAct= req->nKeyActs= 0; + req->totalActs= 0; + return 0; + } + for (nActs=i=0;i<req->nKeyActs;i++) { + if (xkb->server->key_acts[i+req->firstKeyAct]!=0) + nActs+= XkbKeyNumActions(xkb,i+req->firstKeyAct); + } + len= XkbPaddedSize(req->nKeyActs)+(nActs*SIZEOF(xkbActionWireDesc)); + req->totalActs= nActs; + return len; +} + +static void +#if NeedFunctionPrototypes +_XkbWriteKeyActions(Display *dpy,XkbDescPtr xkb,xkbSetMapReq *req) +#else +_XkbWriteKeyActions(dpy,xkb,req) + Display * dpy; + XkbDescPtr xkb; + xkbSetMapReq * req; +#endif +{ + register int i; + int n; + CARD8 *numDesc; + XkbAction *actDesc; + + if ((req->present&XkbKeyActionsMask)==0) + return; + n = XkbPaddedSize(req->nKeyActs); + n+= (req->totalActs*SIZEOF(xkbActionWireDesc)); + + BufAlloc(CARD8 *,numDesc,n); + for (i=0;i<req->nKeyActs;i++) { + if (xkb->server->key_acts[i+req->firstKeyAct]==0) + numDesc[i] = 0; + else numDesc[i] = XkbKeyNumActions(xkb,(i+req->firstKeyAct)); + } + actDesc = (XkbAction *)&numDesc[XkbPaddedSize(req->nKeyActs)]; + for (i=0;i<req->nKeyActs;i++) { + if (xkb->server->key_acts[i+req->firstKeyAct]!=0) { + n = XkbKeyNumActions(xkb,(i+req->firstKeyAct)); + memcpy(actDesc,XkbKeyActionsPtr(xkb,(i+req->firstKeyAct)), + n*SIZEOF(xkbActionWireDesc)); + actDesc+= n; + } + } + return; +} + +static int +#if NeedFunctionPrototypes +_XkbSizeKeyBehaviors(XkbDescPtr xkb,xkbSetMapReq *req) +#else +_XkbSizeKeyBehaviors(xkb,req) + XkbDescPtr xkb; + xkbSetMapReq * req; +#endif +{ +register int i,first,last,nFound; + + if (((req->present&XkbKeyBehaviorsMask)==0)||(req->nKeyBehaviors<1)) { + req->present&= ~XkbKeyBehaviorsMask; + req->firstKeyBehavior= req->nKeyBehaviors= 0; + req->totalKeyBehaviors= 0; + return 0; + } + first= req->firstKeyBehavior; + last= first+req->nKeyBehaviors-1; + for (i=first,nFound=0;i<=last;i++) { + if (xkb->server->behaviors[i].type!=XkbKB_Default) + nFound++; + } + req->totalKeyBehaviors= nFound; + return (nFound*SIZEOF(xkbBehaviorWireDesc)); +} + +static void +#if NeedFunctionPrototypes +_XkbWriteKeyBehaviors(Display *dpy,XkbDescPtr xkb,xkbSetMapReq *req) +#else +_XkbWriteKeyBehaviors(dpy,xkb,req) + Display * dpy; + XkbDescPtr xkb; + xkbSetMapReq * req; +#endif +{ +register int i,first,last; +xkbBehaviorWireDesc * wire; +char * buf; + + if ((req->present&XkbKeyBehaviorsMask)==0) + return; + first= req->firstKeyBehavior; + last= first+req->nKeyBehaviors-1; + + i= req->totalKeyBehaviors*SIZEOF(xkbBehaviorWireDesc); + BufAlloc(char *,buf,i); + wire= (xkbBehaviorWireDesc *)buf; + for (i=first;i<=last;i++) { + if (xkb->server->behaviors[i].type!=XkbKB_Default) { + wire->key= i; + wire->type= xkb->server->behaviors[i].type; + wire->data= xkb->server->behaviors[i].data; + buf+= SIZEOF(xkbBehaviorWireDesc); + wire= (xkbBehaviorWireDesc *)buf; + } + } + return; +} + +static unsigned +#if NeedFunctionPrototypes +_XkbSizeVirtualMods(xkbSetMapReq *req) +#else +_XkbSizeVirtualMods(req) + xkbSetMapReq * req; +#endif +{ +register int i,bit,nMods; + + if (((req->present&XkbVirtualModsMask)==0)||(req->virtualMods==0)) { + req->present&= ~XkbVirtualModsMask; + req->virtualMods= 0; + return 0; + } + for (i=nMods=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) { + if (req->virtualMods&bit) + nMods++; + } + return XkbPaddedSize(nMods); +} + +static void +#if NeedFunctionPrototypes +_XkbWriteVirtualMods( Display * dpy, + XkbDescPtr xkb, + xkbSetMapReq * req, + unsigned size) +#else +_XkbWriteVirtualMods(dpy,xkb,req,size) + Display * dpy; + XkbDescPtr xkb; + xkbSetMapReq * req; + unsigned size; +#endif +{ + register int i,bit; + CARD8 *vmods; + + /* This was req->present&XkbVirtualModsMask==0, and '==' beats '&' */ + if (((req->present & XkbVirtualModsMask) == 0) || (size < 1)) + return; + BufAlloc(CARD8 *,vmods,size); + for (i=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) { + if (req->virtualMods&bit) + *vmods++= xkb->server->vmods[i]; + } + return; +} + +static int +#if NeedFunctionPrototypes +_XkbSizeKeyExplicit(XkbDescPtr xkb,xkbSetMapReq *req) +#else +_XkbSizeKeyExplicit(xkb,req) + XkbDescPtr xkb; + xkbSetMapReq * req; +#endif +{ +register int i,first,last,nFound; + + if (((req->present&XkbExplicitComponentsMask)==0)||(req->nKeyExplicit==0)) { + req->present&= ~XkbExplicitComponentsMask; + req->firstKeyExplicit= req->nKeyExplicit= 0; + req->totalKeyExplicit= 0; + return 0; + } + first= req->firstKeyExplicit; + last= first+req->nKeyExplicit-1; + + for (i=first,nFound=0;i<=last;i++) { + if (xkb->server->explicit[i]!=0) + nFound++; + } + req->totalKeyExplicit= nFound; + return XkbPaddedSize((nFound*2)); +} + +static void +#if NeedFunctionPrototypes +_XkbWriteKeyExplicit(Display *dpy,XkbDescPtr xkb,xkbSetMapReq *req) +#else +_XkbWriteKeyExplicit(dpy,xkb,req) + Display * dpy; + XkbDescPtr xkb; + xkbSetMapReq * req; +#endif +{ +register int i,first,last; +CARD8 * wire; + + if ((req->present&XkbExplicitComponentsMask)==0) + return; + first= req->firstKeyExplicit; + last= first+req->nKeyExplicit; + i= XkbPaddedSize((req->totalKeyExplicit*2)); + BufAlloc(CARD8 *,wire,i); + for (i=first;i<=last;i++) { + if (xkb->server->explicit[i]!=0) { + wire[0]= i; + wire[1]= xkb->server->explicit[i]; + wire+= 2; + } + } + return; +} + +static int +#if NeedFunctionPrototypes +_XkbSizeModifierMap(XkbDescPtr xkb,xkbSetMapReq *req) +#else +_XkbSizeModifierMap(xkb,req) + XkbDescPtr xkb; + xkbSetMapReq * req; +#endif +{ +register int i,first,last,nFound; + + if (((req->present&XkbModifierMapMask)==0)||(req->nModMapKeys==0)) { + req->present&= ~XkbModifierMapMask; + req->firstModMapKey= req->nModMapKeys= 0; + req->totalModMapKeys= 0; + return 0; + } + first= req->firstModMapKey; + last= first+req->nModMapKeys-1; + + for (i=first,nFound=0;i<=last;i++) { + if (xkb->map->modmap[i]!=0) + nFound++; + } + req->totalModMapKeys= nFound; + return XkbPaddedSize((nFound*2)); +} + +static void +#if NeedFunctionPrototypes +_XkbWriteModifierMap(Display *dpy,XkbDescPtr xkb,xkbSetMapReq *req) +#else +_XkbWriteModifierMap(dpy,xkb,req) + Display * dpy; + XkbDescPtr xkb; + xkbSetMapReq * req; +#endif +{ +register int i,first,last; +CARD8 * wire; + + if ((req->present&XkbModifierMapMask)==0) + return; + first= req->firstModMapKey; + last= first+req->nModMapKeys-1; + if (req->totalModMapKeys>0) { + i= XkbPaddedSize((req->totalModMapKeys*2)); + BufAlloc(CARD8 *,wire,i); + for (i=first;i<=last;i++) { + if (xkb->map->modmap[i]!=0) { + wire[0]= i; + wire[1]= xkb->map->modmap[i]; + wire+= 2; + } + } + } + return; +} + +static int +#if NeedFunctionPrototypes +_XkbSizeVirtualModMap(XkbDescPtr xkb,xkbSetMapReq *req) +#else +_XkbSizeVirtualModMap(xkb,req) + XkbDescPtr xkb; + xkbSetMapReq * req; +#endif +{ +register int i,first,last,nFound; + + if (((req->present&XkbVirtualModMapMask)==0)||(req->nVModMapKeys==0)) { + req->present&= ~XkbVirtualModMapMask; + req->firstVModMapKey= req->nVModMapKeys= 0; + req->totalVModMapKeys= 0; + return 0; + } + first= req->firstVModMapKey; + last= first+req->nVModMapKeys-1; + + for (i=first,nFound=0;i<=last;i++) { + if (xkb->server->vmodmap[i]!=0) + nFound++; + } + req->totalVModMapKeys= nFound; + return nFound*SIZEOF(xkbVModMapWireDesc); +} + +static void +#if NeedFunctionPrototypes +_XkbWriteVirtualModMap(Display *dpy,XkbDescPtr xkb,xkbSetMapReq *req) +#else +_XkbWriteVirtualModMap(dpy,xkb,req) + Display * dpy; + XkbDescPtr xkb; + xkbSetMapReq * req; +#endif +{ +register int i,first,last; +xkbVModMapWireDesc * wire; + + if ((req->present&XkbVirtualModMapMask)==0) + return; + first= req->firstVModMapKey; + last= first+req->nVModMapKeys-1; + if (req->totalVModMapKeys>0) { + i= req->totalVModMapKeys*SIZEOF(xkbVModMapWireDesc); + BufAlloc(xkbVModMapWireDesc *,wire,i); + for (i=first;i<=last;i++) { + if (xkb->server->vmodmap[i]!=0) { + wire->key= i; + wire->vmods= xkb->server->vmodmap[i]; + wire++; + } + } + } + return; +} + +static void +#if NeedFunctionPrototypes +SendSetMap(Display *dpy,XkbDescPtr xkb,xkbSetMapReq *req) +#else +SendSetMap(dpy,xkb,req) + Display * dpy; + XkbDescPtr xkb; + xkbSetMapReq * req; +#endif +{ +xkbSetMapReq tmp; +unsigned szMods; + + req->length+= _XkbSizeKeyTypes(xkb,req)/4; + req->length+= _XkbSizeKeySyms(xkb,req)/4; + req->length+= _XkbSizeKeyActions(xkb,req)/4; + req->length+= _XkbSizeKeyBehaviors(xkb,req)/4; + szMods= _XkbSizeVirtualMods(req); + req->length+= szMods/4; + req->length+= _XkbSizeKeyExplicit(xkb,req)/4; + req->length+= _XkbSizeModifierMap(xkb,req)/4; + req->length+= _XkbSizeVirtualModMap(xkb,req)/4; + + tmp= *req; + if ( tmp.nTypes>0 ) + _XkbWriteKeyTypes(dpy,xkb,&tmp); + if ( tmp.nKeySyms>0 ) + _XkbWriteKeySyms(dpy,xkb,&tmp); + if ( tmp.nKeyActs ) + _XkbWriteKeyActions(dpy,xkb,&tmp); + if ( tmp.totalKeyBehaviors>0 ) + _XkbWriteKeyBehaviors(dpy,xkb,&tmp); + if ( tmp.virtualMods ) + _XkbWriteVirtualMods(dpy,xkb,&tmp,szMods); + if ( tmp.totalKeyExplicit>0) + _XkbWriteKeyExplicit(dpy,xkb,&tmp); + if ( tmp.totalModMapKeys>0) + _XkbWriteModifierMap(dpy,xkb,&tmp); + if ( tmp.totalVModMapKeys>0) + _XkbWriteVirtualModMap(dpy,xkb,&tmp); + return; +} + +Bool +#if NeedFunctionPrototypes +XkbSetMap(Display *dpy,unsigned which,XkbDescPtr xkb) +#else +XkbSetMap(dpy,which,xkb) + Display * dpy; + unsigned which; + XkbDescPtr xkb; +#endif +{ +register xkbSetMapReq * req; +XkbInfoPtr xkbi; +XkbServerMapPtr srv; +XkbClientMapPtr map; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))|| + (!xkb)) + return False; + map= xkb->map; + srv= xkb->server; + + if (((which&XkbKeyTypesMask)&&((!map)||(!map->types)))|| + ((which&XkbKeySymsMask)&&((!map)||(!map->syms)||(!map->key_sym_map)))|| + ((which&XkbKeyActionsMask)&&((!srv)||(!srv->key_acts)))|| + ((which&XkbKeyBehaviorsMask)&&((!srv)||(!srv->behaviors)))|| + ((which&XkbVirtualModsMask)&&(!srv))|| + ((which&XkbExplicitComponentsMask)&&((!srv)||(!srv->explicit)))|| + ((which&XkbModifierMapMask)&&((!map)||(!map->modmap)))|| + ((which&XkbVirtualModMapMask)&&((!srv)||(!srv->vmodmap)))) + return False; + + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbSetMap, req); + req->reqType = xkbi->codes->major_opcode; + req->xkbReqType = X_kbSetMap; + req->deviceSpec = xkb->device_spec; + req->present = which; + req->flags = XkbSetMapAllFlags; + req->minKeyCode= xkb->min_key_code; + req->maxKeyCode= xkb->max_key_code; + req->firstType = 0; + if (which&XkbKeyTypesMask) req->nTypes = map->num_types; + else req->nTypes = 0; + if (which&XkbKeySymsMask) { + req->firstKeySym = xkb->min_key_code; + req->nKeySyms = XkbNumKeys(xkb); + } + if (which&XkbKeyActionsMask) { + req->firstKeyAct = xkb->min_key_code; + req->nKeyActs = XkbNumKeys(xkb); + } + if (which&XkbKeyBehaviorsMask) { + req->firstKeyBehavior = xkb->min_key_code; + req->nKeyBehaviors = XkbNumKeys(xkb); + } + if (which&XkbVirtualModsMask) + req->virtualMods= ~0; + if (which&XkbExplicitComponentsMask) { + req->firstKeyExplicit= xkb->min_key_code; + req->nKeyExplicit = XkbNumKeys(xkb); + } + if (which&XkbModifierMapMask) { + req->firstModMapKey= xkb->min_key_code; + req->nModMapKeys = XkbNumKeys(xkb); + } + if (which&XkbVirtualModMapMask) { + req->firstVModMapKey= xkb->min_key_code; + req->nVModMapKeys = XkbNumKeys(xkb); + } + SendSetMap(dpy,xkb,req); + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + +Bool +#if NeedFunctionPrototypes +XkbChangeMap(Display *dpy,XkbDescPtr xkb,XkbMapChangesPtr changes) +#else +XkbChangeMap(dpy,xkb,changes) + Display * dpy; + XkbDescPtr xkb; + XkbMapChangesPtr changes; +#endif +{ +register xkbSetMapReq * req; +XkbInfoPtr xkbi; +XkbServerMapPtr srv; +XkbClientMapPtr map; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))|| + (!xkb)||(!changes)) + return False; + srv= xkb->server; + map= xkb->map; + + if (((changes->changed&XkbKeyTypesMask)&&((!map)||(!map->types)))|| + ((changes->changed&XkbKeySymsMask)&&((!map)||(!map->syms)|| + (!map->key_sym_map)))|| + ((changes->changed&XkbKeyActionsMask)&&((!srv)||(!srv->key_acts)))|| + ((changes->changed&XkbKeyBehaviorsMask)&&((!srv)||(!srv->behaviors)))|| + ((changes->changed&XkbVirtualModsMask)&&(!srv))|| + ((changes->changed&XkbExplicitComponentsMask)&& + ((!srv)||(!srv->explicit)))|| + ((changes->changed&XkbModifierMapMask)&&((!map)||(!map->modmap)))|| + ((changes->changed&XkbVirtualModMapMask)&&((!srv)||(!srv->vmodmap)))) + return False; + + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbSetMap, req); + req->reqType = xkbi->codes->major_opcode; + req->xkbReqType = X_kbSetMap; + req->deviceSpec = xkb->device_spec; + req->present = changes->changed; + req->flags = XkbSetMapRecomputeActions; + req->minKeyCode= xkb->min_key_code; + req->maxKeyCode= xkb->max_key_code; + req->firstType = changes->first_type; + req->nTypes = changes->num_types; + req->firstKeySym = changes->first_key_sym; + req->nKeySyms = changes->num_key_syms; + req->firstKeyAct = changes->first_key_act; + req->nKeyActs = changes->num_key_acts; + req->firstKeyBehavior = changes->first_key_behavior; + req->nKeyBehaviors = changes->num_key_behaviors; + req->virtualMods = changes->vmods; + req->firstKeyExplicit = changes->first_key_explicit; + req->nKeyExplicit = changes->num_key_explicit; + req->firstModMapKey = changes->first_modmap_key; + req->nModMapKeys = changes->num_modmap_keys; + req->firstVModMapKey = changes->first_vmodmap_key; + req->nVModMapKeys = changes->num_vmodmap_keys; + SendSetMap(dpy,xkb,req); + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + diff --git a/src/xkb/XKBUse.c b/src/xkb/XKBUse.c new file mode 100644 index 00000000..1b564cc6 --- /dev/null +++ b/src/xkb/XKBUse.c @@ -0,0 +1,837 @@ +/* $Xorg: XKBUse.c,v 1.3 2000/08/17 19:45:03 cpqbld Exp $ */ +/************************************************************ +Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc. + +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 Silicon Graphics not be +used in advertising or publicity pertaining to distribution +of the software without specific prior written permission. +Silicon Graphics makes no representation about the suitability +of this software for any purpose. It is provided "as is" +without any express or implied warranty. + +SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS +SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON +GRAPHICS 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. + +********************************************************/ + +#include <stdio.h> +#include <ctype.h> +#define NEED_REPLIES +#define NEED_EVENTS +#include "Xlibint.h" +#include <X11/extensions/XKBproto.h> +#include "XKBlibint.h" + +#ifdef X_NOT_STDC_ENV +extern char *getenv(); +#endif + +static Bool _XkbIgnoreExtension = False; + +void +#if NeedFunctionPrototypes +XkbNoteMapChanges(XkbMapChangesPtr old,XkbMapNotifyEvent *new,unsigned wanted) +#else +XkbNoteMapChanges(old,new,wanted) + XkbMapChangesPtr old; + XkbMapNotifyEvent * new; + unsigned int wanted; +#endif +{ + int first,oldLast,newLast; + wanted&= new->changed; + + if (wanted&XkbKeyTypesMask) { + if (old->changed&XkbKeyTypesMask) { + first = old->first_type; + oldLast = old->first_type+old->num_types-1; + newLast = new->first_type+new->num_types-1; + + if (new->first_type<first) + first = new->first_type; + if (oldLast>newLast) + newLast= oldLast; + old->first_type = first; + old->num_types = newLast-first+1; + } + else { + old->first_type= new->first_type; + old->num_types = new->num_types; + } + } + if (wanted&XkbKeySymsMask) { + if (old->changed&XkbKeySymsMask) { + first = old->first_key_sym; + oldLast = old->first_key_sym+old->num_key_syms-1; + newLast = new->first_key_sym+new->num_key_syms-1; + + if (new->first_key_sym<first) + first = new->first_key_sym; + if (oldLast>newLast) + newLast= oldLast; + old->first_key_sym = first; + old->num_key_syms = newLast-first+1; + } + else { + old->first_key_sym = new->first_key_sym; + old->num_key_syms = new->num_key_syms; + } + } + if (wanted&XkbKeyActionsMask) { + if (old->changed&XkbKeyActionsMask) { + first = old->first_key_act; + oldLast = old->first_key_act+old->num_key_acts-1; + newLast = new->first_key_act+new->num_key_acts-1; + + if (new->first_key_act<first) + first = new->first_key_act; + if (oldLast>newLast) + newLast= oldLast; + old->first_key_act = first; + old->num_key_acts = newLast-first+1; + } + else { + old->first_key_act = new->first_key_act; + old->num_key_acts = new->num_key_acts; + } + } + if (wanted&XkbKeyBehaviorsMask) { + if (old->changed&XkbKeyBehaviorsMask) { + first = old->first_key_behavior; + oldLast = old->first_key_behavior+old->num_key_behaviors-1; + newLast = new->first_key_behavior+new->num_key_behaviors-1; + + if (new->first_key_behavior<first) + first = new->first_key_behavior; + if (oldLast>newLast) + newLast= oldLast; + old->first_key_behavior = first; + old->num_key_behaviors = newLast-first+1; + } + else { + old->first_key_behavior = new->first_key_behavior; + old->num_key_behaviors = new->num_key_behaviors; + } + } + if (wanted&XkbVirtualModsMask) { + old->vmods|= new->vmods; + } + if (wanted&XkbExplicitComponentsMask) { + if (old->changed&XkbExplicitComponentsMask) { + first = old->first_key_explicit; + oldLast = old->first_key_explicit+old->num_key_explicit-1; + newLast = new->first_key_explicit+new->num_key_explicit-1; + + if (new->first_key_explicit<first) + first = new->first_key_explicit; + if (oldLast>newLast) + newLast= oldLast; + old->first_key_explicit = first; + old->num_key_explicit = newLast-first+1; + } + else { + old->first_key_explicit = new->first_key_explicit; + old->num_key_explicit = new->num_key_explicit; + } + } + if (wanted&XkbModifierMapMask) { + if (old->changed&XkbModifierMapMask) { + first = old->first_modmap_key; + oldLast = old->first_modmap_key+old->num_modmap_keys-1; + newLast = new->first_modmap_key+new->num_modmap_keys-1; + + if (new->first_modmap_key<first) + first = new->first_modmap_key; + if (oldLast>newLast) + newLast= oldLast; + old->first_modmap_key = first; + old->num_modmap_keys = newLast-first+1; + } + else { + old->first_modmap_key = new->first_modmap_key; + old->num_modmap_keys = new->num_modmap_keys; + } + } + if (wanted&XkbVirtualModMapMask) { + if (old->changed&XkbVirtualModMapMask) { + first = old->first_vmodmap_key; + oldLast = old->first_vmodmap_key+old->num_vmodmap_keys-1; + newLast = new->first_vmodmap_key+new->num_vmodmap_keys-1; + + if (new->first_vmodmap_key<first) + first = new->first_vmodmap_key; + if (oldLast>newLast) + newLast= oldLast; + old->first_vmodmap_key = first; + old->num_vmodmap_keys = newLast-first+1; + } + else { + old->first_vmodmap_key = new->first_vmodmap_key; + old->num_vmodmap_keys = new->num_vmodmap_keys; + } + } + old->changed|= wanted; + return; +} + +void +#if NeedFunctionPrototypes +_XkbNoteCoreMapChanges( XkbMapChangesPtr old, + XMappingEvent * new, + unsigned int wanted) +#else +_XkbNoteCoreMapChanges(old,new,wanted) + XkbMapChangesPtr old; + XMappingEvent * new; + unsigned int wanted; +#endif +{ + int first,oldLast,newLast; + + if ((new->request==MappingKeyboard)&&(wanted&XkbKeySymsMask)) { + if (old->changed&XkbKeySymsMask) { + first = old->first_key_sym; + oldLast = old->first_key_sym+old->num_key_syms-1; + newLast = new->first_keycode+new->count-1; + + if (new->first_keycode<first) + first = new->first_keycode; + if (oldLast>newLast) + newLast= oldLast; + old->first_key_sym = first; + old->num_key_syms = newLast-first+1; + } + else { + old->changed|= XkbKeySymsMask; + old->first_key_sym = new->first_keycode; + old->num_key_syms = new->count; + } + } + return; +} + +static Bool +#if NeedFunctionPrototypes +wire_to_event(Display *dpy,XEvent *re,xEvent *event) +#else +wire_to_event(dpy,re,event) + Display *dpy; + XEvent *re; + xEvent *event; +#endif +{ + xkbEvent *xkbevent= (xkbEvent *)event; + XkbInfoPtr xkbi; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) + return False; + xkbi = dpy->xkb_info; + if (((event->u.u.type&0x7f)-xkbi->codes->first_event)!=XkbEventCode) + return False; + + switch (xkbevent->u.any.xkbType) { + case XkbStateNotify: + { + xkbStateNotify *sn = (xkbStateNotify *)event; + if ( xkbi->selected_events&XkbStateNotifyMask ) { + XkbStateNotifyEvent *sev=(XkbStateNotifyEvent *)re; + sev->type = XkbEventCode+xkbi->codes->first_event; + sev->xkb_type = XkbStateNotify; + sev->serial = _XSetLastRequestRead(dpy, + (xGenericReply *)event); + sev->send_event = ((event->u.u.type & 0x80) != 0); + sev->display = dpy; + sev->time = sn->time; + sev->device = sn->deviceID; + sev->keycode = sn->keycode; + sev->event_type = sn->eventType; + sev->req_major = sn->requestMajor; + sev->req_minor = sn->requestMinor; + sev->changed = sn->changed; + sev->group = sn->group; + sev->base_group = sn->baseGroup; + sev->latched_group = sn->latchedGroup; + sev->locked_group = sn->lockedGroup; + sev->mods = sn->mods; + sev->base_mods = sn->baseMods; + sev->latched_mods = sn->latchedMods; + sev->locked_mods = sn->lockedMods; + sev->compat_state = sn->compatState; + sev->grab_mods = sn->grabMods; + sev->compat_grab_mods = sn->compatGrabMods; + sev->lookup_mods = sn->lookupMods; + sev->compat_lookup_mods = sn->compatLookupMods; + sev->ptr_buttons = sn->ptrBtnState; + return True; + } + } + break; + case XkbMapNotify: + { + xkbMapNotify *mn = (xkbMapNotify *)event; + if ((xkbi->selected_events&XkbMapNotifyMask)&& + (xkbi->selected_map_details&mn->changed)) { + XkbMapNotifyEvent *mev; + mev =(XkbMapNotifyEvent *)re; + mev->type = XkbEventCode+xkbi->codes->first_event; + mev->xkb_type = XkbMapNotify; + mev->serial = _XSetLastRequestRead(dpy, + (xGenericReply *)event); + mev->send_event = ((event->u.u.type&0x80)!=0); + mev->display = dpy; + mev->time = mn->time; + mev->device = mn->deviceID; + mev->changed = mn->changed; + mev->min_key_code = mn->minKeyCode; + mev->max_key_code = mn->maxKeyCode; + mev->first_type = mn->firstType; + mev->num_types = mn->nTypes; + mev->first_key_sym = mn->firstKeySym; + mev->num_key_syms = mn->nKeySyms; + mev->first_key_act = mn->firstKeyAct; + mev->num_key_acts = mn->nKeyActs; + mev->first_key_behavior = mn->firstKeyBehavior; + mev->num_key_behaviors = mn->nKeyBehaviors; + mev->vmods = mn->virtualMods; + mev->first_key_explicit = mn->firstKeyExplicit; + mev->num_key_explicit = mn->nKeyExplicit; + mev->first_modmap_key = mn->firstModMapKey; + mev->num_modmap_keys = mn->nModMapKeys; + mev->first_vmodmap_key = mn->firstVModMapKey; + mev->num_vmodmap_keys = mn->nVModMapKeys; + XkbNoteMapChanges(&xkbi->changes,mev,XKB_XLIB_MAP_MASK); + if (xkbi->changes.changed) + xkbi->flags|= XkbMapPending; + return True; + } + else if (mn->nKeySyms>0) { + register XMappingEvent *ev = (XMappingEvent *)re; + ev->type = MappingNotify; + ev->serial = _XSetLastRequestRead(dpy, + (xGenericReply *)event); + ev->send_event = ((event->u.u.type&0x80)!=0); + ev->display = dpy; + ev->window = 0; + ev->first_keycode = mn->firstKeySym; + ev->request = MappingKeyboard; + ev->count = mn->nKeySyms; + _XkbNoteCoreMapChanges(&xkbi->changes,ev,XKB_XLIB_MAP_MASK); + if (xkbi->changes.changed) + xkbi->flags|= XkbMapPending; + return True; + } + } + break; + case XkbControlsNotify: + { + if (xkbi->selected_events&XkbControlsNotifyMask) { + xkbControlsNotify *cn =(xkbControlsNotify *)event; + XkbControlsNotifyEvent *cev; + cev =(XkbControlsNotifyEvent *)re; + cev->type = XkbEventCode+xkbi->codes->first_event; + cev->xkb_type = XkbControlsNotify; + cev->serial = _XSetLastRequestRead(dpy, + (xGenericReply *)event); + cev->send_event = ((event->u.u.type&0x80)!=0); + cev->display = dpy; + cev->time = cn->time; + cev->device = cn->deviceID; + cev->changed_ctrls = cn->changedControls; + cev->enabled_ctrls = cn->enabledControls; + cev->enabled_ctrl_changes = cn->enabledControlChanges; + cev->keycode = cn->keycode; + cev->num_groups = cn->numGroups; + cev->event_type = cn->eventType; + cev->req_major = cn->requestMajor; + cev->req_minor = cn->requestMinor; + return True; + } + } + break; + case XkbIndicatorMapNotify: + { + if (xkbi->selected_events&XkbIndicatorMapNotifyMask) { + xkbIndicatorNotify *in =(xkbIndicatorNotify *)event; + XkbIndicatorNotifyEvent *iev; + iev =(XkbIndicatorNotifyEvent *)re; + iev->type = XkbEventCode+xkbi->codes->first_event; + iev->xkb_type = XkbIndicatorMapNotify; + iev->serial = _XSetLastRequestRead(dpy, + (xGenericReply *)event); + iev->send_event = ((event->u.u.type&0x80)!=0); + iev->display = dpy; + iev->time = in->time; + iev->device = in->deviceID; + iev->changed = in->changed; + iev->state= in->state; + return True; + } + } + break; + case XkbIndicatorStateNotify: + { + if (xkbi->selected_events&XkbIndicatorStateNotifyMask) { + xkbIndicatorNotify *in =(xkbIndicatorNotify *)event; + XkbIndicatorNotifyEvent *iev; + iev =(XkbIndicatorNotifyEvent *)re; + iev->type = XkbEventCode+xkbi->codes->first_event; + iev->xkb_type = XkbIndicatorStateNotify; + iev->serial = _XSetLastRequestRead(dpy, + (xGenericReply *)event); + iev->send_event = ((event->u.u.type&0x80)!=0); + iev->display = dpy; + iev->time = in->time; + iev->device = in->deviceID; + iev->changed = in->changed; + iev->state= in->state; + return True; + } + } + break; + case XkbBellNotify: + { + if (xkbi->selected_events&XkbBellNotifyMask) { + xkbBellNotify *bn =(xkbBellNotify *)event; + XkbBellNotifyEvent *bev; + bev =(XkbBellNotifyEvent *)re; + bev->type = XkbEventCode+xkbi->codes->first_event; + bev->xkb_type = XkbBellNotify; + bev->serial = _XSetLastRequestRead(dpy, + (xGenericReply *)event); + bev->send_event = ((event->u.u.type&0x80)!=0); + bev->display = dpy; + bev->time = bn->time; + bev->device = bn->deviceID; + bev->percent = bn->percent; + bev->pitch = bn->pitch; + bev->duration = bn->duration; + bev->bell_class = bn->bellClass; + bev->bell_id = bn->bellID; + bev->name = bn->name; + bev->window = bn->window; + bev->event_only = bn->eventOnly; + return True; + } + } + break; + case XkbAccessXNotify: + { + if (xkbi->selected_events&XkbAccessXNotifyMask) { + xkbAccessXNotify *axn =(xkbAccessXNotify *)event; + XkbAccessXNotifyEvent *axev; + axev =(XkbAccessXNotifyEvent *)re; + axev->type = XkbEventCode+xkbi->codes->first_event; + axev->xkb_type = XkbAccessXNotify; + axev->serial = _XSetLastRequestRead(dpy, + (xGenericReply *)event); + axev->send_event = ((event->u.u.type&0x80)!=0); + axev->display = dpy; + axev->time = axn->time; + axev->device = axn->deviceID; + axev->detail = axn->detail; + axev->keycode = axn->keycode; + axev->sk_delay = axn->slowKeysDelay; + axev->debounce_delay = axn->debounceDelay; + return True; + } + } + break; + case XkbNamesNotify: + { + if (xkbi->selected_events&XkbNamesNotifyMask) { + xkbNamesNotify *nn =(xkbNamesNotify *)event; + XkbNamesNotifyEvent *nev; + nev =(XkbNamesNotifyEvent *)re; + nev->type = XkbEventCode+xkbi->codes->first_event; + nev->xkb_type = XkbNamesNotify; + nev->serial = _XSetLastRequestRead(dpy, + (xGenericReply *)event); + nev->send_event = ((event->u.u.type&0x80)!=0); + nev->display = dpy; + nev->time = nn->time; + nev->device = nn->deviceID; + nev->changed = nn->changed; + nev->first_type = nn->firstType; + nev->num_types = nn->nTypes; + nev->first_lvl = nn->firstLevelName; + nev->num_lvls = nn->nLevelNames; + nev->num_aliases = nn->nAliases; + nev->num_radio_groups = nn->nRadioGroups; + nev->changed_vmods = nn->changedVirtualMods; + nev->changed_groups = nn->changedGroupNames; + nev->changed_indicators = nn->changedIndicators; + nev->first_key = nn->firstKey; + nev->num_keys = nn->nKeys; + return True; + } + } + break; + case XkbCompatMapNotify: + { + if (xkbi->selected_events&XkbCompatMapNotifyMask) { + xkbCompatMapNotify *cmn =(xkbCompatMapNotify *)event; + XkbCompatMapNotifyEvent *cmev; + cmev =(XkbCompatMapNotifyEvent *)re; + cmev->type = XkbEventCode+xkbi->codes->first_event; + cmev->xkb_type = XkbCompatMapNotify; + cmev->serial = _XSetLastRequestRead(dpy, + (xGenericReply *)event); + cmev->send_event = ((event->u.u.type&0x80)!=0); + cmev->display = dpy; + cmev->time = cmn->time; + cmev->device = cmn->deviceID; + cmev->changed_groups = cmn->changedGroups; + cmev->first_si = cmn->firstSI; + cmev->num_si = cmn->nSI; + cmev->num_total_si = cmn->nTotalSI; + return True; + } + } + break; + case XkbActionMessage: + { + if (xkbi->selected_events&XkbActionMessageMask) { + xkbActionMessage *am= (xkbActionMessage *)event; + XkbActionMessageEvent *amev; + amev= (XkbActionMessageEvent *)re; + amev->type = XkbEventCode+xkbi->codes->first_event; + amev->xkb_type = XkbActionMessage; + amev->serial = _XSetLastRequestRead(dpy, + (xGenericReply *)event); + amev->send_event = ((event->u.u.type&0x80)!=0); + amev->display = dpy; + amev->time = am->time; + amev->device = am->deviceID; + amev->keycode = am->keycode; + amev->press = am->press; + amev->key_event_follows = am->keyEventFollows; + amev->group = am->group; + amev->mods = am->mods; + memcpy(amev->message,am->message,XkbActionMessageLength); + amev->message[XkbActionMessageLength]= '\0'; + return True; + } + } + break; + case XkbExtensionDeviceNotify: + { + if (xkbi->selected_events&XkbExtensionDeviceNotifyMask) { + xkbExtensionDeviceNotify *ed= + (xkbExtensionDeviceNotify *)event; + XkbExtensionDeviceNotifyEvent *edev; + edev= (XkbExtensionDeviceNotifyEvent *)re; + edev->type= XkbEventCode+xkbi->codes->first_event; + edev->xkb_type= XkbExtensionDeviceNotify; + edev->serial= _XSetLastRequestRead(dpy, + (xGenericReply *)event); + edev->send_event= ((event->u.u.type&0x80)!=0); + edev->display= dpy; + edev->time= ed->time; + edev->device= ed->deviceID; + edev->led_class= ed->ledClass; + edev->led_id= ed->ledID; + edev->reason= ed->reason; + edev->supported= ed->supported; + edev->leds_defined= ed->ledsDefined; + edev->led_state= ed->ledState; + edev->first_btn= ed->firstBtn; + edev->num_btns= ed->nBtns; + edev->unsupported= ed->unsupported; + return True; + } + } + break; + case XkbNewKeyboardNotify: + { + xkbNewKeyboardNotify *nkn = (xkbNewKeyboardNotify *)event; + if ((xkbi->selected_events&XkbNewKeyboardNotifyMask)&& + (xkbi->selected_nkn_details&nkn->changed)) { + XkbNewKeyboardNotifyEvent *nkev; + nkev =(XkbNewKeyboardNotifyEvent *)re; + nkev->type = XkbEventCode+xkbi->codes->first_event; + nkev->xkb_type = XkbNewKeyboardNotify; + nkev->serial = _XSetLastRequestRead(dpy, + (xGenericReply *)event); + nkev->send_event = ((event->u.u.type&0x80)!=0); + nkev->display = dpy; + nkev->time = nkn->time; + nkev->device = nkn->deviceID; + nkev->old_device = nkn->oldDeviceID; + nkev->min_key_code = nkn->minKeyCode; + nkev->max_key_code = nkn->maxKeyCode; + nkev->old_min_key_code = nkn->oldMinKeyCode; + nkev->old_max_key_code = nkn->oldMaxKeyCode; + nkev->req_major = nkn->requestMajor; + nkev->req_minor = nkn->requestMinor; + nkev->changed = nkn->changed; + if ((xkbi->desc)&&(nkev->send_event==0)&& + ((xkbi->desc->device_spec==nkev->old_device)|| + (nkev->device!=nkev->old_device))) { + xkbi->flags= XkbMapPending|XkbXlibNewKeyboard; + } + return True; + } + else if(nkn->changed&(XkbNKN_KeycodesMask|XkbNKN_DeviceIDMask)){ + register XMappingEvent *ev = (XMappingEvent *)re; + ev->type = MappingNotify; + ev->serial = _XSetLastRequestRead(dpy, + (xGenericReply *)event); + ev->send_event = ((event->u.u.type&0x80)!=0); + ev->display = dpy; + ev->window = 0; + ev->first_keycode = dpy->min_keycode; + ev->request = MappingKeyboard; + ev->count = (dpy->max_keycode-dpy->min_keycode)+1; + if ((xkbi->desc)&&(ev->send_event==0)&& + ((xkbi->desc->device_spec==nkn->oldDeviceID)|| + (nkn->deviceID!=nkn->oldDeviceID))) { + xkbi->flags|= XkbMapPending|XkbXlibNewKeyboard; + } + return True; + } + } + break; + default: +#ifdef DEBUG + fprintf(stderr,"Got unknown XKEYBOARD event (%d, base=%d)\n", + re->type, + xkbi->codes->first_event); +#endif + break; + } + return False; +} + +Bool +#if NeedFunctionPrototypes +XkbIgnoreExtension(Bool ignore) +#else +XkbIgnoreExtension(ignore) + Bool ignore; +#endif +{ + if (getenv("XKB_FORCE")!=NULL) { +#ifdef DEBUG + fprintf(stderr,"Forcing use of XKEYBOARD (overriding an IgnoreExtensions)\n"); +#endif + return False; + } +#ifdef DEBUG + else if (getenv("XKB_DEBUG")!=NULL) { + fprintf(stderr,"Explicitly %signoring XKEYBOARD\n",ignore?"":"not "); + } +#endif + _XkbIgnoreExtension = ignore; + return True; +} + +static void +#if NeedFunctionPrototypes +_XkbFreeInfo(Display *dpy) +#else +_XkbFreeInfo(dpy) + Display *dpy; +#endif +{ + XkbInfoPtr xkbi = dpy->xkb_info; + if (xkbi) { + if (xkbi->desc) + XkbFreeKeyboard(xkbi->desc,XkbAllComponentsMask,True); + Xfree(xkbi); + } +} + +Bool +#if NeedFunctionPrototypes +XkbUseExtension(Display *dpy,int *major_rtrn,int *minor_rtrn) +#else +XkbUseExtension(dpy,major_rtrn,minor_rtrn) + Display * dpy; + int * major_rtrn; + int * minor_rtrn; +#endif +{ + xkbUseExtensionReply rep; + register xkbUseExtensionReq *req; + XExtCodes *codes; + int ev_base,forceIgnore; + XkbInfoPtr xkbi; + char * str; + static int debugMsg; + static int been_here= 0; + + if ( dpy->xkb_info ) { + if (major_rtrn) *major_rtrn= dpy->xkb_info->srv_major; + if (minor_rtrn) *minor_rtrn= dpy->xkb_info->srv_minor; + return True; + } + if (!been_here) { + debugMsg= (getenv("XKB_DEBUG")!=NULL); + been_here= 1; + } + + if (major_rtrn) *major_rtrn= 0; + if (minor_rtrn) *minor_rtrn= 0; + + forceIgnore= (dpy->flags&XlibDisplayNoXkb)||dpy->keysyms; + forceIgnore= forceIgnore&(major_rtrn==NULL)&&(minor_rtrn==NULL); + if ( forceIgnore || _XkbIgnoreExtension || getenv("XKB_DISABLE")) { + LockDisplay(dpy); + dpy->flags |= XlibDisplayNoXkb; + UnlockDisplay(dpy); + if (debugMsg) + fprintf(stderr,"XKEYBOARD extension disabled or missing\n"); + return False; + } + + xkbi = _XkbTypedCalloc(1, XkbInfoRec); + if ( !xkbi ) + return False; + + if ( (codes=XInitExtension(dpy,XkbName))==NULL ) { + LockDisplay(dpy); + dpy->flags |= XlibDisplayNoXkb; + UnlockDisplay(dpy); + Xfree(xkbi); + if (debugMsg) + fprintf(stderr,"XKEYBOARD extension not present\n"); + return False; + } + xkbi->codes = codes; + LockDisplay(dpy); + + GetReq(kbUseExtension, req); + req->reqType = xkbi->codes->major_opcode; + req->xkbReqType = X_kbUseExtension; + req->wantedMajor = XkbMajorVersion; + req->wantedMinor = XkbMinorVersion; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse) || !rep.supported ) { + Bool fail; + fail= True; + if (debugMsg) + fprintf(stderr, + "XKEYBOARD version mismatch (want %d.%02d, got %d.%02d)\n", + XkbMajorVersion,XkbMinorVersion, + rep.serverMajor, rep.serverMinor); + + /* pre-release 0.65 is very close to 1.00 */ + if ((rep.serverMajor==0)&&(rep.serverMinor==65)) { + if (debugMsg) + fprintf(stderr,"Trying to fall back to version 0.65..."); + GetReq(kbUseExtension, req); + req->reqType = xkbi->codes->major_opcode; + req->xkbReqType = X_kbUseExtension; + req->wantedMajor = 0; + req->wantedMinor = 65; + if ( _XReply(dpy, (xReply *)&rep, 0, xFalse) && rep.supported ) { + if (debugMsg) + fprintf(stderr,"succeeded\n"); + fail= False; + } + else if (debugMsg) fprintf(stderr,"failed\n"); + } + if (fail) { + dpy->flags |= XlibDisplayNoXkb; + UnlockDisplay(dpy); + SyncHandle(); + Xfree(xkbi); + if (major_rtrn) *major_rtrn= rep.serverMajor; + if (minor_rtrn) *minor_rtrn= rep.serverMinor; + return False; + } + } +#ifdef DEBUG + else if ( forceIgnore ) { + fprintf(stderr,"Internal Error! XkbUseExtension succeeded with forceIgnore set\n"); + } +#endif + UnlockDisplay(dpy); + xkbi->srv_major= rep.serverMajor; + xkbi->srv_minor= rep.serverMinor; + if (major_rtrn) *major_rtrn= rep.serverMajor; + if (minor_rtrn) *minor_rtrn= rep.serverMinor; + if (debugMsg) + fprintf(stderr,"XKEYBOARD (version %d.%02d/%d.%02d) OK!\n", + XkbMajorVersion,XkbMinorVersion, + rep.serverMajor,rep.serverMinor); + dpy->xkb_info = xkbi; + dpy->free_funcs->xkb = _XkbFreeInfo; + ev_base = codes->first_event; + xkbi->xlib_ctrls|= + (XkbLC_BeepOnComposeFail|XkbLC_ComposeLED|XkbLC_ControlFallback); + if ((str=getenv("_XKB_OPTIONS_ENABLE"))!=NULL) { + if ((str=getenv("_XKB_LATIN1_LOOKUP"))!=NULL) { + if ((strcmp(str,"off")==0)||(strcmp(str,"0")==0)) + xkbi->xlib_ctrls&= ~XkbLC_ForceLatin1Lookup; + else xkbi->xlib_ctrls|= XkbLC_ForceLatin1Lookup; + } + if ((str=getenv("_XKB_CONSUME_LOOKUP_MODS"))!=NULL) { + if ((strcmp(str,"off")==0)||(strcmp(str,"0")==0)) + xkbi->xlib_ctrls&= ~XkbLC_ConsumeLookupMods; + else xkbi->xlib_ctrls|= XkbLC_ConsumeLookupMods; + } + if ((str=getenv("_XKB_CONSUME_SHIFT_AND_LOCK"))!=NULL) { + if ((strcmp(str,"off")==0)||(strcmp(str,"0")==0)) + xkbi->xlib_ctrls&= ~XkbLC_AlwaysConsumeShiftAndLock; + else xkbi->xlib_ctrls|= XkbLC_AlwaysConsumeShiftAndLock; + } + if ((str=getenv("_XKB_IGNORE_NEW_KEYBOARDS"))!=NULL) { + if ((strcmp(str,"off")==0)||(strcmp(str,"0")==0)) + xkbi->xlib_ctrls&= ~XkbLC_IgnoreNewKeyboards; + else xkbi->xlib_ctrls|= XkbLC_IgnoreNewKeyboards; + } + if ((str=getenv("_XKB_CONTROL_FALLBACK"))!=NULL) { + if ((strcmp(str,"off")==0)||(strcmp(str,"0")==0)) + xkbi->xlib_ctrls&= ~XkbLC_ControlFallback; + else xkbi->xlib_ctrls|= XkbLC_ControlFallback; + } + if ((str=getenv("_XKB_COMP_LED"))!=NULL) { + if ((strcmp(str,"off")==0)||(strcmp(str,"0")==0)) + xkbi->xlib_ctrls&= ~XkbLC_ComposeLED; + else { + xkbi->xlib_ctrls|= XkbLC_ComposeLED; + if (strlen(str)>0) + xkbi->composeLED= XInternAtom(dpy,str,False); + } + } + if ((str=getenv("_XKB_COMP_FAIL_BEEP"))!=NULL) { + if ((strcmp(str,"off")==0)||(strcmp(str,"0")==0)) + xkbi->xlib_ctrls&= ~XkbLC_BeepOnComposeFail; + else xkbi->xlib_ctrls|= XkbLC_BeepOnComposeFail; + } + } + if ((xkbi->composeLED==None)&&((xkbi->xlib_ctrls&XkbLC_ComposeLED)!=0)) + xkbi->composeLED= XInternAtom(dpy,"Compose",False); +#ifdef DEBUG + if (debugMsg) { + register unsigned c= xkbi->xlib_ctrls; + fprintf(stderr,"XKEYBOARD compose: beep on failure is %s, LED is %s\n", + ((c&XkbLC_BeepOnComposeFail)?"on":"off"), + ((c&XkbLC_ComposeLED)?"on":"off")); + fprintf(stderr,"XKEYBOARD XLookupString: %slatin-1, %s lookup modifiers\n", + ((c&XkbLC_ForceLatin1Lookup)?"allow non-":"force "), + ((c&XkbLC_ConsumeLookupMods)?"consume":"re-use")); + fprintf(stderr, + "XKEYBOARD XLookupString: %sconsume shift and lock, %scontrol fallback\n", + ((c&XkbLC_AlwaysConsumeShiftAndLock)?"always ":"don't "), + ((c&XkbLC_ControlFallback)?"":"no ")); + + } +#endif + XESetWireToEvent(dpy,ev_base+XkbEventCode,wire_to_event); + SyncHandle(); + return True; +} + diff --git a/src/xkb/XKBleds.c b/src/xkb/XKBleds.c new file mode 100644 index 00000000..a4636157 --- /dev/null +++ b/src/xkb/XKBleds.c @@ -0,0 +1,408 @@ +/* $Xorg: XKBleds.c,v 1.3 2000/08/17 19:45:03 cpqbld Exp $ */ +/************************************************************ +Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc. + +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 Silicon Graphics not be +used in advertising or publicity pertaining to distribution +of the software without specific prior written permission. +Silicon Graphics makes no representation about the suitability +of this software for any purpose. It is provided "as is" +without any express or implied warranty. + +SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS +SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON +GRAPHICS 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. + +********************************************************/ + +#define NEED_REPLIES +#define NEED_EVENTS +#include "Xlibint.h" +#include <X11/extensions/XKBproto.h> +#include "XKBlibint.h" + +Status +#if NeedFunctionPrototypes +XkbGetIndicatorState(Display *dpy,unsigned deviceSpec,unsigned *pStateRtrn) +#else +XkbGetIndicatorState(dpy,deviceSpec,pStateRtrn) + Display * dpy; + unsigned int deviceSpec; + unsigned int * pStateRtrn; +#endif +{ + register xkbGetIndicatorStateReq *req; + xkbGetIndicatorStateReply rep; + XkbInfoPtr xkbi; + Bool ok; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) + return BadAccess; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbGetIndicatorState, req); + req->reqType = xkbi->codes->major_opcode; + req->xkbReqType = X_kbGetIndicatorState; + req->deviceSpec = deviceSpec; + ok=_XReply(dpy, (xReply *)&rep, 0, xFalse); + if (ok && (pStateRtrn!=NULL)) + *pStateRtrn= rep.state; + UnlockDisplay(dpy); + SyncHandle(); + return (ok?Success:BadImplementation); +} + +Status +#if NeedFunctionPrototypes +_XkbReadGetIndicatorMapReply( Display * dpy, + xkbGetIndicatorMapReply * rep, + XkbDescPtr xkb, + int * nread_rtrn) +#else +_XkbReadGetIndicatorMapReply(dpy,rep,xkb,nread_rtrn) + Display * dpy; + xkbGetIndicatorMapReply * rep; + XkbDescPtr xkb; + int * nread_rtrn; +#endif +{ +XkbIndicatorPtr leds; +XkbReadBufferRec buf; + + if ((!xkb->indicators)&&(XkbAllocIndicatorMaps(xkb)!=Success)) + return BadAlloc; + leds= xkb->indicators; + + leds->phys_indicators = rep->realIndicators; + if (rep->length>0) { + register int left; + if (!_XkbInitReadBuffer(dpy,&buf,(int)rep->length*4)) + return BadAlloc; + if (nread_rtrn) + *nread_rtrn= (int)rep->length*4; + if (rep->which) { + register int i,bit; + left= (int)rep->which; + for (i=0,bit=1;(i<XkbNumIndicators)&&(left);i++,bit<<=1) { + if (left&bit) { + xkbIndicatorMapWireDesc *wire; + wire= (xkbIndicatorMapWireDesc *) + _XkbGetReadBufferPtr(&buf, + SIZEOF(xkbIndicatorMapWireDesc)); + if (wire==NULL) { + _XkbFreeReadBuffer(&buf); + return BadAlloc; + } + leds->maps[i].flags= wire->flags; + leds->maps[i].which_groups= wire->whichGroups; + leds->maps[i].groups= wire->groups; + leds->maps[i].which_mods= wire->whichMods; + leds->maps[i].mods.mask= wire->mods; + leds->maps[i].mods.real_mods= wire->realMods; + leds->maps[i].mods.vmods= wire->virtualMods; + leds->maps[i].ctrls= wire->ctrls; + left&= ~bit; + } + } + } + left= _XkbFreeReadBuffer(&buf); + } + return Success; +} + +Bool +#if NeedFunctionPrototypes +XkbGetIndicatorMap(Display *dpy,unsigned long which,XkbDescPtr xkb) +#else +XkbGetIndicatorMap(dpy,which,xkb) + Display * dpy; + unsigned long which; + XkbDescPtr xkb; +#endif +{ + register xkbGetIndicatorMapReq * req; + xkbGetIndicatorMapReply rep; + XkbInfoPtr xkbi; + Status status; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) + return BadAccess; + if ((!which)||(!xkb)) + return BadValue; + + LockDisplay(dpy); + xkbi = dpy->xkb_info; + if (!xkb->indicators) { + xkb->indicators = _XkbTypedCalloc(1,XkbIndicatorRec); + if (!xkb->indicators) { + UnlockDisplay(dpy); + SyncHandle(); + return BadAlloc; + } + } + GetReq(kbGetIndicatorMap, req); + req->reqType = xkbi->codes->major_opcode; + req->xkbReqType = X_kbGetIndicatorMap; + req->deviceSpec = xkb->device_spec; + req->which = (CARD32)which; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return BadValue; + } + status= _XkbReadGetIndicatorMapReply(dpy,&rep,xkb,NULL); + UnlockDisplay(dpy); + SyncHandle(); + return status; +} + +Bool +#if NeedFunctionPrototypes +XkbSetIndicatorMap(Display *dpy,unsigned long which,XkbDescPtr xkb) +#else +XkbSetIndicatorMap(dpy,which,xkb) + Display * dpy; + unsigned long which; + XkbDescPtr xkb; +#endif +{ + register xkbSetIndicatorMapReq *req; + register int i,bit; + int nMaps; + xkbIndicatorMapWireDesc *wire; + XkbInfoPtr xkbi; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) + return False; + if ((!xkb)||(!which)||(!xkb->indicators)) + return False; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbSetIndicatorMap, req); + req->reqType = xkbi->codes->major_opcode; + req->xkbReqType = X_kbSetIndicatorMap; + req->deviceSpec = xkb->device_spec; + req->which = (CARD32)which; + for (i=nMaps=0,bit=1;i<32;i++,bit<<=1) { + if (which&bit) + nMaps++; + } + req->length+= (nMaps*sizeof(XkbIndicatorMapRec))/4; + BufAlloc(xkbIndicatorMapWireDesc *,wire, + (nMaps*SIZEOF(xkbIndicatorMapWireDesc))); + for (i=0,bit=1;i<32;i++,bit<<=1) { + if (which&bit) { + wire->flags= xkb->indicators->maps[i].flags; + wire->whichGroups= xkb->indicators->maps[i].which_groups; + wire->groups= xkb->indicators->maps[i].groups; + wire->whichMods= xkb->indicators->maps[i].which_mods; + wire->mods= xkb->indicators->maps[i].mods.real_mods; + wire->virtualMods= xkb->indicators->maps[i].mods.vmods; + wire->ctrls= xkb->indicators->maps[i].ctrls; + wire++; + } + } + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + +Bool +#if NeedFunctionPrototypes +XkbGetNamedDeviceIndicator( Display * dpy, + unsigned device, + unsigned class, + unsigned id, + Atom name, + int * pNdxRtrn, + Bool * pStateRtrn, + XkbIndicatorMapPtr pMapRtrn, + Bool * pRealRtrn) +#else +XkbGetNamedDeviceIndicator(dpy,device,class,id,name,pNdxRtrn,pStateRtrn, + pMapRtrn,pRealRtrn) + Display * dpy; + unsigned device; + unsigned class; + unsigned id; + Atom name; + int * pNdxRtrn; + Bool * pStateRtrn; + XkbIndicatorMapPtr pMapRtrn; + Bool * pRealRtrn; +#endif +{ + register xkbGetNamedIndicatorReq *req; + xkbGetNamedIndicatorReply rep; + XkbInfoPtr xkbi; + + if ((dpy->flags & XlibDisplayNoXkb) || (name==None) || + (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) + return False; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbGetNamedIndicator, req); + req->reqType = xkbi->codes->major_opcode; + req->xkbReqType = X_kbGetNamedIndicator; + req->deviceSpec = device; + req->ledClass = class; + req->ledID = id; + req->indicator = (CARD32)name; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + if ((!rep.found)||(!rep.supported)) + return False; + if (pNdxRtrn!=NULL) + *pNdxRtrn= rep.ndx; + if (pStateRtrn!=NULL) + *pStateRtrn= rep.on; + if (pMapRtrn!=NULL) { + pMapRtrn->flags= rep.flags; + pMapRtrn->which_groups= rep.whichGroups; + pMapRtrn->groups= rep.groups; + pMapRtrn->which_mods= rep.whichMods; + pMapRtrn->mods.mask= rep.mods; + pMapRtrn->mods.real_mods= rep.realMods; + pMapRtrn->mods.vmods= rep.virtualMods; + pMapRtrn->ctrls= rep.ctrls; + } + if (pRealRtrn!=NULL) + *pRealRtrn= rep.realIndicator; + return True; +} + +Bool +#if NeedFunctionPrototypes +XkbGetNamedIndicator( Display * dpy, + Atom name, + int * pNdxRtrn, + Bool * pStateRtrn, + XkbIndicatorMapPtr pMapRtrn, + Bool * pRealRtrn) +#else +XkbGetNamedIndicator(dpy,name,pNdxRtrn,pStateRtrn,pMapRtrn,pRealRtrn) + Display * dpy; + Atom name; + int * pNdxRtrn; + Bool * pStateRtrn; + XkbIndicatorMapPtr pMapRtrn; + Bool * pRealRtrn; +#endif +{ + return XkbGetNamedDeviceIndicator(dpy,XkbUseCoreKbd, + XkbDfltXIClass,XkbDfltXIId, + name,pNdxRtrn,pStateRtrn, + pMapRtrn,pRealRtrn); +} + +Bool +#if NeedFunctionPrototypes +XkbSetNamedDeviceIndicator( Display * dpy, + unsigned device, + unsigned class, + unsigned id, + Atom name, + Bool changeState, + Bool state, + Bool createNewMap, + XkbIndicatorMapPtr pMap) +#else +XkbSetNamedDeviceIndicator(dpy,device,class,id,name,changeState, + state,createNewMap,pMap) + Display * dpy; + unsigned device; + unsigned class; + unsigned id; + Atom name; + Bool changeState; + Bool state; + Bool createNewMap; + XkbIndicatorMapPtr pMap; +#endif +{ + register xkbSetNamedIndicatorReq *req; + XkbInfoPtr xkbi; + + if ((dpy->flags & XlibDisplayNoXkb) || (name==None) || + (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL)) || + (pMap==NULL)) + return False; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbSetNamedIndicator, req); + req->reqType = xkbi->codes->major_opcode; + req->xkbReqType = X_kbSetNamedIndicator; + req->deviceSpec = device; + req->ledClass = class; + req->ledID = id; + req->indicator= (CARD32)name; + req->setState= changeState; + if (req->setState) + req->on= state; + else req->on= False; + if (pMap!=NULL) { + req->setMap= True; + req->createMap= createNewMap; + req->flags= pMap->flags; + req->whichGroups= pMap->which_groups; + req->groups= pMap->groups; + req->whichMods= pMap->which_mods; + req->realMods= pMap->mods.real_mods; + req->virtualMods= pMap->mods.vmods; + req->ctrls= pMap->ctrls; + } + else { + req->setMap= False; + req->createMap= False; + req->flags= 0; + req->whichGroups= 0; + req->groups= 0; + req->whichMods= 0; + req->realMods= 0; + req->virtualMods= 0; + req->ctrls= 0; + } + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + +Bool +#if NeedFunctionPrototypes +XkbSetNamedIndicator( Display * dpy, + Atom name, + Bool changeState, + Bool state, + Bool createNewMap, + XkbIndicatorMapPtr pMap) +#else +XkbSetNamedIndicator(dpy,name,changeState,state,createNewMap,pMap) + Display * dpy; + Atom name; + Bool changeState; + Bool state; + Bool createNewMap; + XkbIndicatorMapPtr pMap; +#endif +{ + return XkbSetNamedDeviceIndicator(dpy,XkbUseCoreKbd, + XkbDfltXIClass,XkbDfltXIId, + name,changeState,state, + createNewMap,pMap); +} diff --git a/src/xkb/XKBlibint.h b/src/xkb/XKBlibint.h new file mode 100644 index 00000000..5247cb7c --- /dev/null +++ b/src/xkb/XKBlibint.h @@ -0,0 +1,406 @@ +/* $Xorg: XKBlibint.h,v 1.3 2000/08/17 19:45:04 cpqbld Exp $ */ +/************************************************************ +Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc. + +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 Silicon Graphics not be +used in advertising or publicity pertaining to distribution +of the software without specific prior written permission. +Silicon Graphics makes no representation about the suitability +of this software for any purpose. It is provided "as is" +without any express or implied warranty. + +SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS +SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON +GRAPHICS 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. + +********************************************************/ + +#ifndef _XKBLIBINT_H_ +#define _XKBLIBINT_H_ + +#include <X11/Xutil.h> +#include <X11/XKBlib.h> + +#define XkbMapPending (1<<0) +#define XkbXlibNewKeyboard (1<<1) + +typedef int (*XkbKSToMBFunc)( +#if NeedFunctionPrototypes + XPointer /* priv */, + KeySym /* sym */, + char * /* buf */, + int /* len */, + int * /* extra_rtrn */ +#endif +); + +typedef KeySym (*XkbMBToKSFunc)( +#if NeedFunctionPrototypes + XPointer /* priv */, + char * /* buf */, + int /* len */, + Status * /* status */ +#endif +); + +typedef KeySym (*XkbToUpperFunc)( +#if NeedFunctionPrototypes + KeySym /* sym */ +#endif +); + +typedef struct _XkbConverters { + XkbKSToMBFunc KSToMB; + XPointer KSToMBPriv; + XkbMBToKSFunc MBToKS; + XPointer MBToKSPriv; + XkbToUpperFunc KSToUpper; +} XkbConverters; + +extern XkbInternAtomFunc _XkbInternAtomFunc; +extern XkbGetAtomNameFunc _XkbGetAtomNameFunc; + +typedef struct _XkbInfoRec { + unsigned flags; + unsigned xlib_ctrls; + XExtCodes *codes; + int srv_major; + int srv_minor; + unsigned selected_events; + unsigned short selected_nkn_details; + unsigned short selected_map_details; + XkbDescRec *desc; + XkbMapChangesRec changes; + Atom composeLED; + XkbConverters cvt; + XkbConverters latin1cvt; +} XkbInfoRec, *XkbInfoPtr; + + +#define _XkbUnavailable(d) \ + (((d)->flags&XlibDisplayNoXkb) ||\ + ((!(d)->xkb_info || (!(d)->xkb_info->desc)) && !_XkbLoadDpy(d))) + +#define _XkbCheckPendingRefresh(d,xi) {\ + if ((xi)->flags&XkbXlibNewKeyboard)\ + _XkbReloadDpy((d));\ + else if ((xi)->flags&XkbMapPending) {\ + if (XkbGetMapChanges((d),(xi)->desc, &(xi)->changes)==Success) {\ + LockDisplay((d));\ + (xi)->changes.changed= 0;\ + UnlockDisplay((d));\ + }\ + }\ +} + +#define _XkbNeedModmap(i) ((!(i)->desc->map)||(!(i)->desc->map->modmap)) + + /* + * mask of the events that the "invisible" XKB support in Xlib needs + */ +#define XKB_XLIB_MAP_MASK (XkbAllClientInfoMask) + + /* + * Handy helper macros + */ +#define XKB_INSURE_SIZE(f,t,nNum,oNum) {\ + if ((f)==NULL) \ + (f)=(t *)Xmalloc(sizeof(t)*(nNum));\ + else if ((nNum)<(oNum))\ + (f)=(t *)Xrealloc((f),sizeof(t)*(nNum));\ + } + +typedef struct _XkbReadBuffer { + int error; + int size; + char *start; + char *data; +} XkbReadBufferRec,*XkbReadBufferPtr; + +#define _XkbAlloc(s) Xmalloc((s)) +#define _XkbCalloc(n,s) Xcalloc((n),(s)) +#define _XkbRealloc(o,s) Xrealloc((o),(s)) +#define _XkbTypedAlloc(t) ((t *)Xmalloc(sizeof(t))) +#define _XkbTypedCalloc(n,t) ((t *)Xcalloc((n),sizeof(t))) +#define _XkbTypedRealloc(o,n,t) \ + ((o)?(t *)Xrealloc((o),(n)*sizeof(t)):_XkbTypedCalloc(n,t)) +#define _XkbClearElems(a,f,l,t) bzero(&(a)[f],((l)-(f)+1)*sizeof(t)) +#define _XkbFree(p) Xfree(p) + +_XFUNCPROTOBEGIN + +extern void _XkbReloadDpy( +#if NeedFunctionPrototypes + Display * /* dpy */ +#endif +); + +extern KeySym _XKeycodeToKeysym( +#if NeedFunctionPrototypes + Display* /* display */, + KeyCode /* keycode */, + int /* index */ +#endif +); + +extern KeyCode _XKeysymToKeycode( +#if NeedFunctionPrototypes + Display* /* display */, + KeySym /* keysym */ +#endif +); + +extern KeySym _XLookupKeysym( +#if NeedFunctionPrototypes + XKeyEvent* /* key_event */, + int /* index */ +#endif +); + +extern int _XRefreshKeyboardMapping( +#if NeedFunctionPrototypes + XMappingEvent* /* event_map */ +#endif +); + +extern unsigned _XKeysymToModifiers( +#if NeedFunctionPrototypes + Display * /* dpy */, + KeySym /* ks */ +#endif +); + +extern int _XTranslateKey( +#if NeedFunctionPrototypes + register Display * /* dpy */, + KeyCode /* keycode */, + register unsigned int /* modifiers */, + unsigned int * /* modifiers_return */, + KeySym * /* keysym_return */ +#endif +); + +extern int _XTranslateKeySym( +#if NeedFunctionPrototypes + Display * /* dpy */, + register KeySym /* symbol */, + unsigned int /* modifiers */, + char * /* buffer */, + int /* nbytes */ +#endif +); + +extern int _XLookupString( +#if NeedFunctionPrototypes + register XKeyEvent * /* event */, + char * /* buffer */, + int /* nbytes */, + KeySym * /* keysym */, + XComposeStatus * /* status */ +#endif +); + +extern void _XkbNoteCoreMapChanges( +#if NeedFunctionPrototypes + XkbMapChangesRec * /* old */, + XMappingEvent * /* new */, + unsigned int /* wanted */ +#endif +); + +extern int _XkbInitReadBuffer( +#if NeedFunctionPrototypes + Display * /* dpy */, + XkbReadBufferPtr /* buf */, + int /* size */ +#endif +); + +extern int _XkbSkipReadBufferData( +#if NeedFunctionPrototypes + XkbReadBufferPtr /* from */, + int /* size */ +#endif +); + +extern int _XkbCopyFromReadBuffer( +#if NeedFunctionPrototypes + XkbReadBufferPtr /* from */, + char * /* to */, + int /* size */ +#endif +); + + +#if defined(WORD64) || defined(LONG64) +extern int _XkbReadCopyData32( +#if NeedFunctionPrototypes + int * /* from */, + long * /* to */, + int /* num_words */ +#endif +); + +extern int _XkbWriteCopyData32( +#if NeedFunctionPrototypes + unsigned long * /* from */, + CARD32 * /* to */, + int /* num_words */ +#endif +); + +extern int _XkbReadBufferCopy32( +#if NeedFunctionPrototypes + XkbReadBufferPtr /* from */, + long * /* to */, + int /* size */ +#endif +); +#else +#define _XkbReadCopyData32(f,t,s) memcpy((char *)(t),(char *)(f),(s)*4) +#define _XkbWriteCopyData32(f,t,s) memcpy((char *)(t),(char *)(f),(s)*4) +#define _XkbReadBufferCopy32(f,t,s) _XkbCopyFromReadBuffer(f,(char *)t,(s)*4) +#endif + +#ifndef NO_DEC_BINARY_COMPATIBILITY +#define XKB_FORCE_INT_KEYSYM 1 +#endif + +#ifdef XKB_FORCE_INT_KEYSYM +extern int _XkbReadCopyKeySyms( +#if NeedFunctionPrototypes + int * /* from */, + KeySym * /* to */, + int /* num_words */ +#endif +); + +extern int _XkbWriteCopyKeySyms( +#if NeedFunctionPrototypes + KeySym * /* from */, + CARD32 * /* to */, + int /* num_words */ +#endif +); + +extern int _XkbReadBufferCopyKeySyms( +#if NeedFunctionPrototypes + XkbReadBufferPtr /* from */, +#ifndef NO_DEC_BUG_FIX + KeySym * /* to */, +#else + long * /* to */, +#endif + int /* size */ +#endif +); +#else +#define _XkbReadCopyKeySyms(f,t,n) _XkbReadCopyData32(f,t,n) +#define _XkbWriteCopyKeySyms(f,t,n) _XkbWriteCopyData32(f,t,n) +#define _XkbReadBufferCopyKeySyms(f,t,s) _XkbReadBufferCopy32(f,t,s) +#endif + +extern char *_XkbPeekAtReadBuffer( +#if NeedFunctionPrototypes + XkbReadBufferPtr /* from */, + int /* size */ +#endif +); + +extern char *_XkbGetReadBufferPtr( +#if NeedFunctionPrototypes + XkbReadBufferPtr /* from */, + int /* size */ +#endif +); +#define _XkbGetTypedRdBufPtr(b,n,t) ((t *)_XkbGetReadBufferPtr(b,(n)*SIZEOF(t))) + +extern int _XkbFreeReadBuffer( +#if NeedFunctionPrototypes + XkbReadBufferPtr /* buf */ +#endif +); + +extern Bool +_XkbGetReadBufferCountedString( +#if NeedFunctionPrototypes + XkbReadBufferPtr /* buf */, + char ** /* rtrn */ +#endif +); + +extern char *_XkbGetCharset( +#if NeedFunctionPrototypes + void +#endif +); + +extern int _XkbGetConverters( +#if NeedFunctionPrototypes + char * /* encoding_name */, + XkbConverters * /* cvt_rtrn */ +#endif +); + +#ifdef NEED_MAP_READERS + +extern Status _XkbReadGetMapReply( +#if NeedFunctionPrototypes + Display * /* dpy */, + xkbGetMapReply * /* rep */, + XkbDescRec * /* xkb */, + int * /* nread_rtrn */ +#endif +); + +extern Status _XkbReadGetCompatMapReply( +#if NeedFunctionPrototypes + Display * /* dpy */, + xkbGetCompatMapReply * /* rep */, + XkbDescPtr /* xkb */, + int * /* nread_rtrn */ +#endif +); + +extern Status _XkbReadGetIndicatorMapReply( +#if NeedFunctionPrototypes + Display * /* dpy */, + xkbGetIndicatorMapReply * /* rep */, + XkbDescPtr /* xkb */, + int * /* nread_rtrn */ +#endif +); + +extern Status _XkbReadGetNamesReply( +#if NeedFunctionPrototypes + Display * /* dpy */, + xkbGetNamesReply * /* rep */, + XkbDescPtr /* xkb */, + int * /* nread_rtrn */ +#endif +); + +extern Status _XkbReadGetGeometryReply( +#if NeedFunctionPrototypes + Display * /* dpy */, + xkbGetGeometryReply * /* rep */, + XkbDescPtr /* xkb */, + int * /* nread_rtrn */ +#endif +); + +#endif + +_XFUNCPROTOEND + +#endif /* _XKBLIBINT_H_ */ diff --git a/src/xlibi18n/ICWrap.c b/src/xlibi18n/ICWrap.c new file mode 100644 index 00000000..be511f4a --- /dev/null +++ b/src/xlibi18n/ICWrap.c @@ -0,0 +1,475 @@ +/* + * $Xorg: ICWrap.c,v 1.4 2001/02/09 02:03:33 xorgcvs Exp $ + */ + +/* + * Copyright 1990, 1991 by OMRON Corporation, NTT Software Corporation, + * and Nippon Telegraph and Telephone Corporation + * Copyright 1991 by the Open Software Foundation + * Copyright 1993 by the FUJITSU LIMITED + * + * 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 names of OMRON, NTT Software, NTT, and + * Open Software Foundation not be used in advertising or publicity + * pertaining to distribution of the software without specific, + * written prior permission. OMRON, NTT Software, NTT, and Open Software + * Foundation make no representations about the suitability of this + * software for any purpose. It is provided "as is" without express or + * implied warranty. + * + * OMRON, NTT SOFTWARE, NTT, AND OPEN SOFTWARE FOUNDATION + * DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING + * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT + * SHALL OMRON, NTT SOFTWARE, NTT, OR OPEN SOFTWARE FOUNDATION 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. + * + * Authors: Li Yuhong OMRON Corporation + * Tatsuya Kato NTT Software Corporation + * Hiroshi Kuribayashi OMRON Coproration + * Muneiyoshi Suzuki Nippon Telegraph and Telephone Co. + * + * M. Collins OSF + * Takashi Fujiwara FUJITSU LIMITED + */ +/* + +Copyright 1991, 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. + +*/ + +#define NEED_EVENTS +#include "Xlibint.h" +#include "Xlcint.h" + +static int +_XIMNestedListToNestedList(nlist, list) + XIMArg *nlist; /* This is the new list */ + XIMArg *list; /* The original list */ +{ + register XIMArg *ptr = list; + + while (ptr->name) { + if (!strcmp(ptr->name, XNVaNestedList)) { + nlist += _XIMNestedListToNestedList(nlist, (XIMArg *)ptr->value); + } else { + nlist->name = ptr->name; + nlist->value = ptr->value; + ptr++; + nlist++; + } + } + return ptr - list; +} + +static void +_XIMCountNestedList(args, total_count) + XIMArg *args; + int *total_count; +{ + for (; args->name; args++) { + if (!strcmp(args->name, XNVaNestedList)) + _XIMCountNestedList((XIMArg *)args->value, total_count); + else + ++(*total_count); + } +} + +#if NeedVarargsPrototypes +static void +_XIMCountVaList(va_list var, int *total_count) +#else +static void +_XIMCountVaList(var, total_count) + va_list var; + int *total_count; +#endif +{ + char *attr; + + *total_count = 0; + + for (attr = va_arg(var, char*); attr; attr = va_arg(var, char*)) { + if (!strcmp(attr, XNVaNestedList)) { + _XIMCountNestedList(va_arg(var, XIMArg*), total_count); + } else { + va_arg(var, XIMArg*); + ++(*total_count); + } + } +} + +#if NeedVarargsPrototypes +static void +_XIMVaToNestedList(va_list var, int max_count, XIMArg **args_return) +#else +static void +_XIMVaToNestedList(var, max_count, args_return) + va_list var; + int max_count; + XIMArg **args_return; +#endif +{ + XIMArg *args; + char *attr; + + if (max_count <= 0) { + *args_return = (XIMArg *)NULL; + return; + } + + args = (XIMArg *)Xmalloc((unsigned)(max_count + 1) * sizeof(XIMArg)); + *args_return = args; + if (!args) return; + + for (attr = va_arg(var, char*); attr; attr = va_arg(var, char*)) { + if (!strcmp(attr, XNVaNestedList)) { + args += _XIMNestedListToNestedList(args, va_arg(var, XIMArg*)); + } else { + args->name = attr; + args->value = va_arg(var, XPointer); + args++; + } + } + args->name = (char*)NULL; +} + +/*ARGSUSED*/ +#if NeedVarargsPrototypes +XVaNestedList +XVaCreateNestedList(int dummy, ...) +#else +XVaNestedList +XVaCreateNestedList(dummy, va_alist) + int dummy; + va_dcl +#endif +{ + va_list var; + XIMArg *args = NULL; + int total_count; + + Va_start(var, dummy); + _XIMCountVaList(var, &total_count); + va_end(var); + + Va_start(var, dummy); + _XIMVaToNestedList(var, total_count, &args); + va_end(var); + + return (XVaNestedList)args; +} + +#if NeedVarargsPrototypes +char * +XSetIMValues(XIM im, ...) +#else /* NeedVarargsPrototypes */ +char * +XSetIMValues(im, va_alist) + XIM im; + va_dcl +#endif /* NeedVarargsPrototypes */ +{ + va_list var; + int total_count; + XIMArg *args; + char *ret; + + /* + * so count the stuff dangling here + */ + Va_start(var, im); + _XIMCountVaList(var, &total_count); + va_end(var); + + /* + * now package it up so we can send it along + */ + Va_start(var, im); + _XIMVaToNestedList(var, total_count, &args); + va_end(var); + + ret = (*im->methods->set_values) (im, args); + if (args) Xfree((char *)args); + return ret; +} + +#if NeedVarargsPrototypes +char * +XGetIMValues(XIM im, ...) +#else /* NeedVarargsPrototypes */ +char * +XGetIMValues(im, va_alist) + XIM im; + va_dcl +#endif /* NeedVarargsPrototypes */ +{ + va_list var; + int total_count; + XIMArg *args; + char *ret; + + /* + * so count the stuff dangling here + */ + Va_start(var, im); + _XIMCountVaList(var, &total_count); + va_end(var); + + /* + * now package it up so we can send it along + */ + Va_start(var, im); + _XIMVaToNestedList(var, total_count, &args); + va_end(var); + + ret = (*im->methods->get_values) (im, args); + if (args) Xfree((char *)args); + return ret; +} + +/* + * Create an input context within the input method, + * and return a pointer to the input context. + */ + +#if NeedVarargsPrototypes +XIC +XCreateIC(XIM im, ...) +#else +XIC +XCreateIC(im, va_alist) + XIM im; /* specified the attached input method */ + va_dcl /* specified variable length argment list */ +#endif +{ + va_list var; + int total_count; + XIMArg *args; + XIC ic; + + /* + * so count the stuff dangling here + */ + Va_start(var, im); + _XIMCountVaList(var, &total_count); + va_end(var); + + /* + * now package it up so we can send it along + */ + Va_start(var, im); + _XIMVaToNestedList(var, total_count, &args); + va_end(var); + + ic = (XIC) (*im->methods->create_ic) (im, args); + if (args) Xfree((char *)args); + if (ic) { + ic->core.next = im->core.ic_chain; + im->core.ic_chain = ic; + } + return ic; +} + +/* + * Free the input context. + */ +void +XDestroyIC(ic) + XIC ic; +{ + XIM im = ic->core.im; + XIC *prev; + + (*ic->methods->destroy) (ic); + if (im) { + for (prev = &im->core.ic_chain; *prev; prev = &(*prev)->core.next) { + if (*prev == ic) { + *prev = ic->core.next; + break; + } + } + } + Xfree ((char *) ic); +} + +#if NeedVarargsPrototypes +char * +XGetICValues(XIC ic, ...) +#else +char * +XGetICValues(ic, va_alist) + XIC ic; + va_dcl +#endif +{ + va_list var; + int total_count; + XIMArg *args; + char *ret; + + if (!ic->core.im) + return (char *) NULL; + + /* + * so count the stuff dangling here + */ + Va_start(var, ic); + _XIMCountVaList(var, &total_count); + va_end(var); + + /* + * now package it up so we can send it along + */ + Va_start(var, ic); + _XIMVaToNestedList(var, total_count, &args); + va_end(var); + + ret = (*ic->methods->get_values) (ic, args); + if (args) Xfree((char *)args); + return ret; +} + +#if NeedVarargsPrototypes +char * +XSetICValues(XIC ic, ...) +#else +char * +XSetICValues(ic, va_alist) + XIC ic; + va_dcl +#endif +{ + va_list var; + int total_count; + XIMArg *args; + char *ret; + + if (!ic->core.im) + return (char *) NULL; + + /* + * so count the stuff dangling here + */ + Va_start(var, ic); + _XIMCountVaList(var, &total_count); + va_end(var); + + /* + * now package it up so we can send it along + */ + Va_start(var, ic); + _XIMVaToNestedList(var, total_count, &args); + va_end(var); + + ret = (*ic->methods->set_values) (ic, args); + if (args) Xfree((char *)args); + return ret; +} + +/* + * Require the input manager to focus the focus window attached to the ic + * argument. + */ +void +XSetICFocus(ic) + XIC ic; +{ + if (ic->core.im) + (*ic->methods->set_focus) (ic); +} + +/* + * Require the input manager to unfocus the focus window attached to the ic + * argument. + */ +void +XUnsetICFocus(ic) + XIC ic; +{ + if (ic->core.im) + (*ic->methods->unset_focus) (ic); +} + +/* + * Return the XIM associated with the input context. + */ +XIM +XIMOfIC(ic) + XIC ic; +{ + return ic->core.im; +} + +char *XmbResetIC(ic) + XIC ic; +{ + if (ic->core.im) + return (*ic->methods->mb_reset)(ic); + return (char *)NULL; +} + +wchar_t *XwcResetIC(ic) + XIC ic; +{ + if (ic->core.im) + return (*ic->methods->wc_reset)(ic); + return (wchar_t *)NULL; +} + +int +XmbLookupString(ic, ev, buffer, nbytes, keysym, status) + XIC ic; + register XKeyEvent *ev; + char *buffer; + int nbytes; + KeySym *keysym; + Status *status; +{ + if (ic->core.im) + return (*ic->methods->mb_lookup_string) (ic, ev, buffer, nbytes, + keysym, status); + return XLookupNone; +} + +int +XwcLookupString(ic, ev, buffer, nchars, keysym, status) + XIC ic; + register XKeyEvent *ev; + wchar_t *buffer; + int nchars; + KeySym *keysym; + Status *status; +{ + if (ic->core.im) + return (*ic->methods->wc_lookup_string) (ic, ev, buffer, nchars, + keysym, status); + return XLookupNone; +} diff --git a/src/xlibi18n/IMWrap.c b/src/xlibi18n/IMWrap.c new file mode 100644 index 00000000..fc8e6426 --- /dev/null +++ b/src/xlibi18n/IMWrap.c @@ -0,0 +1,218 @@ +/* + * $Xorg: IMWrap.c,v 1.4 2001/02/09 02:03:33 xorgcvs Exp $ + */ + +/* + * Copyright 1991 by the Open Software Foundation + * Copyright 1993, 1994 by the Sony Corporation + * + * 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 names of Open Software Foundation and + * Sony Corporation not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior permission. + * Open Software Foundation and Sony Corporation make no + * representations about the suitability of this software for any purpose. + * It is provided "as is" without express or implied warranty. + * + * OPEN SOFTWARE FOUNDATION AND SONY CORPORATION DISCLAIM ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL OPEN + * SOFTWARE FOUNDATIONN OR SONY CORPORATION 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. + * + * M. Collins OSF + * Makoto Wakamatsu Sony Corporation + */ +/* + +Copyright 1991, 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. + +*/ + +#include "Xlibint.h" +#include "Xlcint.h" + +/* + * Compile the resource name. (resource_name ---> xrm_name) + */ +void +_XIMCompileResourceList(res, num_res) + register XIMResourceList res; + unsigned int num_res; +{ + register unsigned int count; + + for (count = 0; count < num_res; res++, count++) { + res->xrm_name = XrmStringToQuark(res->resource_name); + } +} + +void +_XCopyToArg(src, dst, size) + XPointer src; + XPointer *dst; + register unsigned int size; +{ + if (!*dst) { + union { + long longval; +#ifdef LONG64 + int intval; +#endif + short shortval; + char charval; + char* charptr; + XPointer ptr; + } u; + if (size <= sizeof(XPointer)) { + memcpy((char *)&u, (char *)src, (int)size); + if (size == sizeof(long)) *dst = (XPointer)u.longval; +#ifdef LONG64 + else if (size == sizeof(int)) *dst = (XPointer)u.intval; +#endif + else if (size == sizeof(short)) *dst = (XPointer)(long)u.shortval; + else if (size == sizeof(char)) *dst = (XPointer)(long)u.charval; + else if (size == sizeof(char*)) *dst = (XPointer)u.charptr; + else if (size == sizeof(XPointer)) *dst = (XPointer)u.ptr; + else memcpy( (char*)dst, (char*)src, (int)size ); + } else { + memcpy( (char*)dst, (char*)src, (int)size ); + } + } else { + memcpy( (char*)*dst, (char*)src, (int)size ); + } +} + +/* + * Connects to an input method matching current locale specification, creates + * a XIM object and return a pointer the newly created XIM back to the caller. + */ + +XIM +XOpenIM( display, rdb, res_name, res_class ) + Display *display; + XrmDatabase rdb; + char *res_name; + char *res_class; +{ + XLCd lcd = _XOpenLC( (char *)NULL ); + + if( !lcd ) + return( (XIM)NULL ); + return (*lcd->methods->open_im) (lcd, display, rdb, res_name, res_class); +} + +/* + * Close the connection to the input manager, and free the XIM structure + */ +Status +XCloseIM(im) + XIM im; +{ + Status s; + XIC ic; + XLCd lcd = im->core.lcd; + + s = (im->methods->close) (im); + for (ic = im->core.ic_chain; ic; ic = ic->core.next) + ic->core.im = (XIM)NULL; + Xfree ((char *) im); + _XCloseLC (lcd); + return (s); +} + +/* + * Return the Display associated with the input method. + */ +Display * +XDisplayOfIM(im) + XIM im; +{ + return im->core.display; +} + +/* + * Return the Locale associated with the input method. + */ +char * +XLocaleOfIM(im) + XIM im; +{ + return im->core.lcd->core->name; +} + +/* + * Register to a input method instantiation callback to prepare the + * on-demand input method instantiation. + */ +Bool +XRegisterIMInstantiateCallback( display, rdb, res_name, res_class, callback, + client_data) + Display *display; + XrmDatabase rdb; + char *res_name; + char *res_class; + XIMProc callback; + XPointer *client_data; +{ + XLCd lcd = _XOpenLC( (char *)NULL ); + + if( !lcd ) + return( False ); + return( (*lcd->methods->register_callback)( lcd, display, rdb, res_name, + res_class, callback, + client_data ) ); +} + +/* + * Unregister to a input method instantiation callback. + */ +Bool +XUnregisterIMInstantiateCallback( display, rdb, res_name, res_class, callback, + client_data ) + Display *display; + XrmDatabase rdb; + char *res_name; + char *res_class; + XIMProc callback; + XPointer *client_data; +{ + XLCd lcd = _XlcCurrentLC(); + + if( !lcd ) + return( False ); + if( lcd->methods->unregister_callback == NULL ) + return( False ); + return( (*lcd->methods->unregister_callback)( lcd, display, rdb, res_name, + res_class, callback, + client_data ) ); +} + diff --git a/src/xlibi18n/XDefaultIMIF.c b/src/xlibi18n/XDefaultIMIF.c new file mode 100644 index 00000000..e31c207b --- /dev/null +++ b/src/xlibi18n/XDefaultIMIF.c @@ -0,0 +1,501 @@ +/* +Copyright 1985, 1986, 1987, 1991, 1998 The Open Group + +Portions Copyright 2000 Sun Microsystems, Inc. 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 THE OPEN GROUP OR SUN MICROSYSTEMS, INC. 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 EVEN IF +ADVISED IN ADVANCE OF THE POSSIBILITY OF SUCH DAMAGES. + + +Except as contained in this notice, the names of The Open Group and/or +Sun Microsystems, Inc. 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 and/or Sun Microsystems, +Inc., as applicable. + + +X Window System is a trademark of The Open Group + +OSF/1, OSF/Motif and Motif are registered trademarks, and OSF, the OSF +logo, LBX, X Window System, and Xinerama are trademarks of the Open +Group. All other trademarks and registered trademarks mentioned herein +are the property of their respective owners. No right, title or +interest in or to any trademark, service mark, logo or trade name of +Sun Microsystems, Inc. or its licensors is granted. + +*/ + +#include <stdio.h> +#define NEED_EVENTS +#include "Xlibint.h" +#include "Xlcint.h" +#include "XlcGeneric.h" + +#ifndef MAXINT +#define MAXINT (~((unsigned int)1 << (8 * sizeof(int)) - 1)) +#endif /* !MAXINT */ + +typedef struct _StaticXIM *StaticXIM; + +typedef struct _XIMStaticXIMRec { + /* for CT => MB,WC converter */ + XlcConv ctom_conv; + XlcConv ctow_conv; +} XIMStaticXIMRec; + +typedef enum { + CREATE_IC = 1, + SET_ICVAL = 2, + GET_ICVAL = 3 +} XICOp_t; + +typedef struct _StaticXIM { + XIMMethods methods; + XIMCoreRec core; + XIMStaticXIMRec *private; +} StaticXIMRec; + +static Status _CloseIM( +#if NeedFunctionPrototypes + XIM +#endif +); + +static char *_SetIMValues( +#if NeedFunctionPrototypes + XIM, XIMArg * +#endif +); + +static char *_GetIMValues( +#if NeedFunctionPrototypes + XIM, XIMArg* +#endif +); + +static XIC _CreateIC( +#if NeedFunctionPrototypes + XIM, XIMArg* +#endif +); + +static _Xconst XIMMethodsRec local_im_methods = { + _CloseIM, /* close */ + _SetIMValues, /* set_values */ + _GetIMValues, /* get_values */ + _CreateIC, /* create_ic */ + NULL, /* ctstombs */ + NULL /* ctstowcs */ +}; + +static void _DestroyIC( +#if NeedFunctionPrototypes + XIC +#endif +); +static void _SetFocus( +#if NeedFunctionPrototypes + XIC +#endif +); +static void _UnsetFocus( +#if NeedFunctionPrototypes + XIC +#endif +); +static char* _SetICValues( +#if NeedFunctionPrototypes + XIC, XIMArg * +#endif +); +static char* _GetICValues( +#if NeedFunctionPrototypes + XIC, XIMArg * +#endif +); +static char *_MbReset( +#if NeedFunctionPrototypes + XIC +#endif +); +static wchar_t *_WcReset( +#if NeedFunctionPrototypes + XIC +#endif +); +static int _MbLookupString( +#if NeedFunctionPrototypes + XIC, XKeyEvent *, char *, int, KeySym *, Status * +#endif +); +static int _WcLookupString( +#if NeedFunctionPrototypes + XIC, XKeyEvent *, wchar_t *, int, KeySym *, Status * +#endif +); + +static _Xconst XICMethodsRec local_ic_methods = { + _DestroyIC, /* destroy */ + _SetFocus, /* set_focus */ + _UnsetFocus, /* unset_focus */ + _SetICValues, /* set_values */ + _GetICValues, /* get_values */ + _MbReset, /* mb_reset */ + _WcReset, /* wc_reset */ + _MbLookupString, /* mb_lookup_string */ + _WcLookupString, /* wc_lookup_string */ +}; + +XIM +_XDefaultOpenIM(lcd, dpy, rdb, res_name, res_class) +XLCd lcd; +Display *dpy; +XrmDatabase rdb; +char *res_name, *res_class; +{ + FILE *fp; + char *name; + StaticXIM im; + XIMStaticXIMRec *local_impart; + XlcConv ctom_conv, ctow_conv; + int i; + char *mod; + char buf[BUFSIZ]; + + if (!(ctom_conv = _XlcOpenConverter(lcd, + XlcNCompoundText, lcd, XlcNMultiByte))) { + return((XIM)NULL); + } + + if (!(ctow_conv = _XlcOpenConverter(lcd, + XlcNCompoundText, lcd, XlcNWideChar))) { + return((XIM)NULL); + } + + if ((im = (StaticXIM)Xmalloc(sizeof(StaticXIMRec))) == (StaticXIM)NULL) { + return((XIM)NULL); + } + if ((local_impart = (XIMStaticXIMRec*)Xmalloc(sizeof(XIMStaticXIMRec))) + == (XIMStaticXIMRec *)NULL) { + Xfree(im); + return((XIM)NULL); + } + memset(im, 0, sizeof(StaticXIMRec)); + memset(local_impart, 0, sizeof(XIMStaticXIMRec)); + + buf[0] = '\0'; + i = 0; + if ((lcd->core->modifiers) && (*lcd->core->modifiers)) { +#define MODIFIER "@im=" + mod = strstr(lcd->core->modifiers, MODIFIER); + if (mod) { + mod += strlen(MODIFIER); + while (*mod && *mod != '@' && i < BUFSIZ - 1) { + buf[i++] = *mod++; + } + buf[i] = '\0'; + } + } +#undef MODIFIER + if ((im->core.im_name = Xmalloc(i+1)) == NULL) + goto Error2; + strcpy(im->core.im_name, buf); + + im->private = local_impart; + im->methods = (XIMMethods)&local_im_methods; + im->core.lcd = lcd; + im->core.ic_chain = (XIC)NULL; + im->core.display = dpy; + im->core.rdb = rdb; + im->core.res_name = NULL; + im->core.res_class = NULL; + + local_impart->ctom_conv = ctom_conv; + local_impart->ctow_conv = ctow_conv; + + if ((res_name != NULL) && (*res_name != '\0')){ + im->core.res_name = (char *)Xmalloc(strlen(res_name)+1); + strcpy(im->core.res_name,res_name); + } + if ((res_class != NULL) && (*res_class != '\0')){ + im->core.res_class = (char *)Xmalloc(strlen(res_class)+1); + strcpy(im->core.res_class,res_class); + } + + return (XIM)im; +Error1 : + if(im->core.im_name) + Xfree(im->core.im_name); +Error2 : + Xfree(im->private); + Xfree(im->core.im_name); + Xfree(im); + _XlcCloseConverter(ctom_conv); + _XlcCloseConverter(ctow_conv); + return(NULL); +} + +static Status +_CloseIM(xim) +XIM xim; +{ + StaticXIM im = (StaticXIM)xim; + _XlcCloseConverter(im->private->ctom_conv); + _XlcCloseConverter(im->private->ctow_conv); + XFree(im->private); + XFree(im->core.im_name); + if (im->core.res_name) XFree(im->core.res_name); + if (im->core.res_class) XFree(im->core.res_class); + return 1; /*bugID 4163122*/ +} + +static char * +_SetIMValues(xim, arg) +XIM xim; +XIMArg *arg; +{ + return(arg->name); /* evil */ +} + +static char * +_GetIMValues(xim, values) +XIM xim; +XIMArg *values; +{ + XIMArg *p; + XIMStyles **value; + XIMStyles *styles; + int i; + XIMStyles *p_style; + + for (p = values; p->name != NULL; p++) { + if (strcmp(p->name, XNQueryInputStyle) == 0) { + styles = (XIMStyles *)Xmalloc(sizeof(XIMStyles)); + *(XIMStyles **)p->value = styles; + styles->count_styles = 1; + styles->supported_styles = + (XIMStyle*)Xmalloc(styles->count_styles * sizeof(XIMStyle)); + styles->supported_styles[0] = (XIMPreeditNone | XIMStatusNone); + } else { + break; + } + } + return (p->name); +} + +static char* +_SetICValueData(ic, values, mode) +XIC ic; +XIMArg *values; +XICOp_t mode; +{ + XIMArg *p; + int i; + char *return_name = NULL; + + for (p = values; p != NULL && p->name != NULL; p++) { + if(strcmp(p->name, XNInputStyle) == 0) { + if (mode == CREATE_IC) + ic->core.input_style = (XIMStyle)p->value; + } else if (strcmp(p->name, XNClientWindow) == 0) { + ic->core.client_window = (Window)p->value ; + } else if (strcmp(p->name, XNFocusWindow) == 0) { + ic->core.focus_window = (Window)p->value ; + } else if (strcmp(p->name, XNPreeditAttributes) == 0 + || strcmp(p->name, XNStatusAttributes) == 0) { + return_name = _SetICValueData(ic, (XIMArg*)p->value, mode); + if (return_name) break; + } else { + return_name = p->name; + break; + } + } + return(return_name); +} + +static char* +_GetICValueData(ic, values, mode) +XIC ic; +XIMArg *values; +XICOp_t mode; +{ + XIMArg *p; + char *return_name = NULL; + + for (p = values; p->name != NULL; p++) { + if(strcmp(p->name, XNInputStyle) == 0) { + *((XIMStyle *)(p->value)) = ic->core.input_style; + } else if (strcmp(p->name, XNClientWindow) == 0) { + *((Window *)(p->value)) = ic->core.client_window; + } else if (strcmp(p->name, XNFocusWindow) == 0) { + *((Window *)(p->value)) = ic->core.focus_window; + } else if (strcmp(p->name, XNFilterEvents) == 0) { + *((unsigned long *)(p->value))= ic->core.filter_events; + } else if (strcmp(p->name, XNPreeditAttributes) == 0 + || strcmp(p->name, XNStatusAttributes) == 0) { + return_name = _GetICValueData(ic, (XIMArg*)p->value, mode); + if (return_name) break; + } else { + return_name = p->name; + break; + } + } + return(return_name); +} + +static XIC +_CreateIC(im, arg) +XIM im; +XIMArg *arg; +{ + XIC ic; + + if ((ic = (XIC)Xmalloc(sizeof(XICRec))) == (XIC)NULL) { + return ((XIC)NULL); + } + memset(ic, 0, sizeof(XICRec)); + + ic->methods = (XICMethods)&local_ic_methods; + ic->core.im = im; + ic->core.filter_events = KeyPressMask; + + if (_SetICValueData(ic, arg, CREATE_IC) != NULL) + goto err_return; + if (!(ic->core.input_style)) + goto err_return; + + return (XIC)ic; +err_return: + XFree(ic); + return ((XIC)NULL); +} + +static void +_DestroyIC(ic) +XIC ic; +{ +/*BugId4255571. This Xfree() should be removed because XDestroyIC() still need ic after invoking _DestroyIC() and there is a XFree(ic) at the end of XDestroyIC() already. + if(ic) + XFree(ic); */ +} + +static void +_SetFocus(ic) +XIC ic; +{ +} + +static void +_UnsetFocus(ic) +XIC ic; +{ +} + +static char* +_SetICValues(ic, args) +XIC ic; +XIMArg *args; +{ + char *ret = NULL; + if (!ic) { + return (args->name); + } + ret = _SetICValueData(ic, args, SET_ICVAL); + return(ret); +} + +static char* +_GetICValues(ic, args) +XIC ic; +XIMArg *args; +{ + char *ret = NULL; + if (!ic) { + return (args->name); + } + ret = _GetICValueData(ic, args, GET_ICVAL); + return(ret); +} + +static char * +_MbReset(xic) +XIC xic; +{ + return(NULL); +} + +static wchar_t * +_WcReset(xic) +XIC xic; +{ + return(NULL); +} + +static int +_MbLookupString(xic, ev, buffer, bytes, keysym, status) +XIC xic; +XKeyEvent *ev; +char * buffer; +int bytes; +KeySym *keysym; +Status *status; +{ + XComposeStatus NotSupportedYet ; + int length; + + length = XLookupString(ev, buffer, bytes, keysym, &NotSupportedYet); + + if (keysym && *keysym == NoSymbol){ + *status = XLookupNone; + } else if (length > 0) { + *status = XLookupBoth; + } else { + *status = XLookupKeySym; + } + return(length); +} + +static int +_WcLookupString(xic, ev, buffer, wlen, keysym, status) +XIC xic; +XKeyEvent *ev; +wchar_t * buffer; +int wlen; +KeySym *keysym; +Status *status; +{ + XComposeStatus NotSupportedYet ; + int length; + /* In single-byte, mb_len = wc_len */ + char *mb_buf = (char *)Xmalloc(wlen); + + length = XLookupString(ev, mb_buf, wlen, keysym, &NotSupportedYet); + + if (keysym && *keysym == NoSymbol){ + *status = XLookupNone; + } else if (length > 0) { + *status = XLookupBoth; + } else { + *status = XLookupKeySym; + } + mbstowcs(buffer, mb_buf, length); + XFree(mb_buf); + return(length); +} diff --git a/src/xlibi18n/XDefaultOMIF.c b/src/xlibi18n/XDefaultOMIF.c new file mode 100644 index 00000000..1bb09dac --- /dev/null +++ b/src/xlibi18n/XDefaultOMIF.c @@ -0,0 +1,1372 @@ +/* +Copyright 1985, 1986, 1987, 1991, 1998 The Open Group + +Portions Copyright 2000 Sun Microsystems, Inc. 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 THE OPEN GROUP OR SUN MICROSYSTEMS, INC. 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 EVEN IF +ADVISED IN ADVANCE OF THE POSSIBILITY OF SUCH DAMAGES. + + +Except as contained in this notice, the names of The Open Group and/or +Sun Microsystems, Inc. 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 and/or Sun Microsystems, +Inc., as applicable. + + +X Window System is a trademark of The Open Group + +OSF/1, OSF/Motif and Motif are registered trademarks, and OSF, the OSF +logo, LBX, X Window System, and Xinerama are trademarks of the Open +Group. All other trademarks and registered trademarks mentioned herein +are the property of their respective owners. No right, title or +interest in or to any trademark, service mark, logo or trade name of +Sun Microsystems, Inc. or its licensors is granted. + +*/ +#include "Xlibint.h" +#include "Xlcint.h" +#include "XlcPublic.h" +#include <X11/Xos.h> +#include <X11/Xatom.h> +#include <stdio.h> + +#define MAXFONTS 100 + +#define XOM_GENERIC(om) (&((XOMGeneric) om)->gen) +#define XOC_GENERIC(font_set) (&((XOCGeneric) font_set)->gen) + +#define DefineLocalBuf char local_buf[BUFSIZ] +#define AllocLocalBuf(length) (length > BUFSIZ ? (char *)Xmalloc(length) : local_buf) +#define FreeLocalBuf(ptr) if (ptr != local_buf) Xfree(ptr) + +typedef struct _FontDataRec { + char *name; +} FontDataRec, *FontData; + +typedef struct _OMDataRec { + int font_data_count; + FontData font_data; +} OMDataRec, *OMData; + +typedef struct _XOMGenericPart { + OMData data; +} XOMGenericPart; + +typedef struct _XOMGenericRec { + XOMMethods methods; + XOMCoreRec core; + XOMGenericPart gen; +} XOMGenericRec, *XOMGeneric; + +typedef struct _FontSetRec { + int id; + int font_data_count; + FontData font_data; + char *font_name; + XFontStruct *info; + XFontStruct *font; +} FontSetRec, *FontSet; + +typedef struct _XOCGenericPart { + XlcConv wcs_to_cs; + FontSet font_set; +} XOCGenericPart; + +typedef struct _XOCGenericRec { + XOCMethods methods; + XOCCoreRec core; + XOCGenericPart gen; +} XOCGenericRec, *XOCGeneric; + +static Bool +init_fontset(oc) + XOC oc; +{ + XOCGenericPart *gen; + FontSet font_set; + OMData data; + + data = XOM_GENERIC(oc->core.om)->data; + + font_set = (FontSet) Xmalloc(sizeof(FontSetRec)); + if (font_set == NULL) + return False; + bzero((char *) font_set, sizeof(FontSetRec)); + + gen = XOC_GENERIC(oc); + gen->font_set = font_set; + + font_set->font_data_count = data->font_data_count; + font_set->font_data = data->font_data; + + return True; +} + +static char * +get_prop_name(dpy, fs) + Display *dpy; + XFontStruct *fs; +{ + unsigned long fp; + + if (XGetFontProperty(fs, XA_FONT, &fp)) + return XGetAtomName(dpy, fp); + + return (char *) NULL; +} + +static FontData +check_charset(font_set, font_name) + FontSet font_set; + char *font_name; +{ + FontData font_data; + char *last; + int count; + ssize_t length, name_len; + + name_len = strlen(font_name); + last = font_name + name_len; + + count = font_set->font_data_count; + font_data = font_set->font_data; + + for ( ; count-- > 0; font_data++) { + length = strlen(font_data->name); + + if (length > name_len) + return(NULL); + + if (_XlcCompareISOLatin1(last - length, font_data->name) == 0) + return font_data; + } + return (FontData) NULL; +} + +static int +check_fontname(oc, name) +XOC oc; +char *name; +{ + Display *dpy = oc->core.om->core.display; + XOCGenericPart *gen = XOC_GENERIC(oc); + FontData data; + FontSet font_set; + XFontStruct *fs_list; + char **fn_list, *fname, *prop_fname = NULL; + int list_num, i; + int list2_num; + char **fn2_list = NULL; + int found_num = 0; + + fn_list = XListFonts(dpy, name, MAXFONTS, &list_num); + if (fn_list == NULL) + return found_num; + + for (i = 0; i < list_num; i++) { + fname = fn_list[i]; + + font_set = gen->font_set; + + if ((data = check_charset(font_set, fname)) == NULL) { + if ((fn2_list = XListFontsWithInfo(dpy, name, MAXFONTS, + &list2_num, &fs_list)) + && (prop_fname = get_prop_name(dpy, fs_list)) + && (data = check_charset(font_set, prop_fname))) + fname = prop_fname; + } + if (data) { + font_set->font_name = (char *) Xmalloc(strlen(fname) + 1); + if (font_set->font_name) { + strcpy(font_set->font_name, fname); + found_num++; + } + } + if (fn2_list) { + XFreeFontInfo(fn2_list, fs_list, list2_num); + fn2_list = NULL; + if (prop_fname) { + Xfree(prop_fname); + prop_fname = NULL; + } + } + if (found_num == 1) + break; + } + XFreeFontNames(fn_list); + return found_num; +} + +static Bool +load_font(oc) + XOC oc; +{ + Display *dpy = oc->core.om->core.display; + XOCGenericPart *gen = XOC_GENERIC(oc); + FontSet font_set = gen->font_set; + + if (font_set->font_name == NULL) + return False; + + if (font_set->font == NULL) { + font_set->font = XLoadQueryFont(dpy, font_set->font_name); + if (font_set->font == NULL) + return False; + } + return True; +} + +static Bool +load_font_info(oc) + XOC oc; +{ + Display *dpy = oc->core.om->core.display; + XOCGenericPart *gen = XOC_GENERIC(oc); + FontSet font_set = gen->font_set; + char **fn_list; + int fn_num; + + if (font_set->font_name == NULL) + return False; + + if (font_set->info == NULL) { + fn_list = XListFontsWithInfo(dpy, font_set->font_name, 1, &fn_num, + &font_set->info); + if (font_set->info == NULL) + return False; + if (fn_num > 0) + font_set->info->fid = XLoadFont(dpy, font_set->font_name); + + if (fn_list) XFreeFontNames(fn_list); + } + return True; +} + +static void +set_fontset_extents(oc) + XOC oc; +{ + XRectangle *ink = &oc->core.font_set_extents.max_ink_extent; + XRectangle *logical = &oc->core.font_set_extents.max_logical_extent; + XFontStruct **font_list, *font; + XCharStruct overall; + int logical_ascent, logical_descent; + + font_list = oc->core.font_info.font_struct_list; + font = *font_list++; + overall = font->max_bounds; + overall.lbearing = font->min_bounds.lbearing; + logical_ascent = font->ascent; + logical_descent = font->descent; + + ink->x = overall.lbearing; + ink->y = -(overall.ascent); + ink->width = overall.rbearing - overall.lbearing; + ink->height = overall.ascent + overall.descent; + + logical->x = 0; + logical->y = -(logical_ascent); + logical->width = overall.width; + logical->height = logical_ascent + logical_descent; +} + +static Bool +init_core_part(oc) + XOC oc; +{ + XOCGenericPart *gen = XOC_GENERIC(oc); + FontSet font_set; + XFontStruct **font_struct_list; + char **font_name_list, *font_name_buf; + int count, length; + + font_set = gen->font_set; + count = length = 0; + + if (font_set->font_name != NULL) { + length += strlen(font_set->font_name) + 1; + count++; + } + if (count == 0) + return False; + + font_struct_list = (XFontStruct **) Xmalloc(sizeof(XFontStruct *)); + if (font_struct_list == NULL) + return False; + + font_name_list = (char **) Xmalloc(sizeof(char *)); + if (font_name_list == NULL) + goto err; + + font_name_buf = (char *) Xmalloc(length); + if (font_name_buf == NULL) + goto err; + + oc->core.font_info.num_font = 1; + oc->core.font_info.font_name_list = font_name_list; + oc->core.font_info.font_struct_list = font_struct_list; + + font_set = gen->font_set; + + if (font_set->font_name != NULL) { + font_set->id = 1; + if (font_set->font) + *font_struct_list++ = font_set->font; + else + *font_struct_list++ = font_set->info; + strcpy(font_name_buf, font_set->font_name); + Xfree(font_set->font_name); + *font_name_list++ = font_set->font_name = font_name_buf; + font_name_buf += strlen(font_name_buf) + 1; + } + + set_fontset_extents(oc); + + return True; + +err: + if (font_name_list) + Xfree(font_name_list); + Xfree(font_struct_list); + + return False; +} + +static char * +get_font_name(oc, pattern) + XOC oc; + char *pattern; +{ + char **list, *name, *prop_name; + int count; + XFontStruct *fs; + Display *dpy = oc->core.om->core.display; + + list = XListFonts(dpy, pattern, 1, &count); + if (list != NULL) { + name = (char *) Xmalloc(strlen(*list) + 1); + if (name) + strcpy(name, *list); + + XFreeFontNames(list); + } else { + fs = XLoadQueryFont(dpy, pattern); + if (fs == NULL) return NULL; + + prop_name = get_prop_name(dpy, fs); + if (prop_name == NULL) return NULL; + + name = (char*) Xmalloc(strlen(prop_name) + 1); + if (name) + strcpy(name, prop_name); + + XFreeFont(dpy, fs); + } + return name; +} + +static int +parse_fontname(oc) + XOC oc; +{ + XOCGenericPart *gen = XOC_GENERIC(oc); + FontSet font_set; + FontData font_data; + char *pattern, *last, buf[BUFSIZ]; + int font_data_count, found_num = 0; + ssize_t length; + int count, num_fields; + char *base_name, *font_name, **name_list, **cur_name_list; + char *charset_p; + Bool append_charset; + /* + append_charset flag should be set to True when the XLFD fontname + doesn't contain a chaset part. + */ + + name_list = _XParseBaseFontNameList(oc->core.base_name_list, &count); + if (name_list == NULL) + return -1; + cur_name_list = name_list; + + while (count-- > 0) { + pattern = *cur_name_list++; + if (pattern == NULL || *pattern == '\0') + continue; + + append_charset = False; + + if (strchr(pattern, '*') == NULL && + (font_name = get_font_name(oc, pattern))) { + + font_set = gen->font_set; + + font_data = check_charset(font_set, font_name); + if (font_data == NULL) { + Display *dpy = oc->core.om->core.display; + char **fn_list = NULL, *prop_fname = NULL; + int list_num; + XFontStruct *fs_list; + if ((fn_list = XListFontsWithInfo(dpy, font_name, + MAXFONTS, + &list_num, &fs_list)) + && (prop_fname = get_prop_name(dpy, fs_list)) + && (font_data = check_charset(font_set, prop_fname))) { + if (fn_list) { + XFreeFontInfo(fn_list, fs_list, list_num); + fn_list = NULL; + } + font_name = prop_fname; + } + } + if (font_data == NULL) + continue; + + font_set->font_name = (char *) Xmalloc(strlen(font_name) + 1); + if (font_set->font_name == NULL) { + Xfree(font_name); + goto err; + } + strcpy(font_set->font_name, font_name); + Xfree(font_name); + found_num++; + goto found; + } +/* +1266793 +Limit the length of the string copy to prevent stack corruption. + strcpy(buf, pattern); +*/ + strncpy(buf, pattern, BUFSIZ); + buf[BUFSIZ-1] = '\0'; + length = strlen(buf); + last = buf + length - 1; + + for (num_fields = 0, base_name = buf; *base_name != '\0'; base_name++) + if (*base_name == '-') num_fields++; + if (strchr(pattern, '*') == NULL) { + if (num_fields == 12) { + append_charset = True; + *++last = '-'; + last++; + } else + continue; + } else { + if (num_fields == 13 || num_fields == 14) { + /* + * There are 14 fields in an XLFD name -- make certain the + * charset (& encoding) is placed in the correct field. + */ + append_charset = True; + last = strrchr (buf, '-'); + if (num_fields == 14) { + *last = '\0'; + last = strrchr (buf, '-'); + } + last++; + } else if (*last == '*') { + append_charset = True; + if (length > 3 && *(last-3) == '-' && *(last-2) == '*' + && *(last-1) == '-') { + last -= 2; + } + *++last = '-'; + last++; + } else { + last = strrchr (buf, '-'); + charset_p = last; + charset_p = strrchr (buf, '-'); + while (*(--charset_p) != '-'); + charset_p++; + } + } + + font_set = gen->font_set; + + font_data = font_set->font_data; + font_data_count = font_set->font_data_count; + for ( ; font_data_count-- > 0; font_data++) { + if (append_charset) + { +/* +1266793 +Limit the length of the string copy to prevent stack corruption. + strcpy(last, font_data->name); +*/ + strncpy(last, font_data->name, BUFSIZ - length); + buf[BUFSIZ-1] = '\0'; + } + else { + if (_XlcCompareISOLatin1(charset_p, + font_data->name)) { + continue; + } + } + if ((font_set->font_name = get_font_name(oc, buf))) + break; + } + if (font_set->font_name != NULL) { + found_num++; + goto found; + } + } + found: + base_name = (char *) Xmalloc(strlen(oc->core.base_name_list) + 1); + if (base_name == NULL) + goto err; + + strcpy(base_name, oc->core.base_name_list); + oc->core.base_name_list = base_name; + + XFreeStringList(name_list); + + return found_num; +err: + XFreeStringList(name_list); + + return -1; +} + +static Bool +set_missing_list(oc) + XOC oc; +{ + XOCGenericPart *gen = XOC_GENERIC(oc); + FontSet font_set; + char **charset_list, *charset_buf; + int count, length; + + font_set = gen->font_set; + count = length = 0; + + if (!font_set->info && !font_set->font) { + length += strlen(font_set->font_data->name) + 1; + count++; + } + + if (count == 0) + return True; + + charset_list = (char **) Xmalloc(sizeof(char *)); + if (charset_list == NULL) + return False; + + charset_buf = (char *) Xmalloc(length); + if (charset_buf == NULL) { + Xfree(charset_list); + return False; + } + + oc->core.missing_list.charset_list = charset_list; + + font_set = gen->font_set; + + if (!font_set->info && !font_set->font) { + strcpy(charset_buf, font_set->font_data->name); + *charset_list++ = charset_buf; + charset_buf += strlen(charset_buf) + 1; + } + return True; +} + +static Bool +create_fontset(oc) + XOC oc; +{ + XOMGenericPart *gen = XOM_GENERIC(oc->core.om); + int found_num; + + if (init_fontset(oc) == False) + return False; + + found_num = parse_fontname(oc); + if (found_num <= 0) { + if (found_num == 0) + set_missing_list(oc); + return False; + } + + if (load_font(oc) == False) + return False; + + if (init_core_part(oc) == False) + return False; + + if (set_missing_list(oc) == False) + return False; + + return True; +} + +static void +destroy_oc(oc) + XOC oc; +{ + Display *dpy = oc->core.om->core.display; + XOCGenericPart *gen = XOC_GENERIC(oc); + XFontStruct **font_list, *font; + + if (gen->font_set) + Xfree(gen->font_set); + + if (oc->core.base_name_list) + Xfree(oc->core.base_name_list); + + if (oc->core.font_info.font_name_list) + XFreeStringList(oc->core.font_info.font_name_list); + + if (font_list = oc->core.font_info.font_struct_list) { + if (font = *font_list) { + if (font->fid) + XFreeFont(dpy, font); + else + XFreeFontInfo(NULL, font, 1); + } + Xfree(oc->core.font_info.font_struct_list); + } + + if (oc->core.missing_list.charset_list) + XFreeStringList(oc->core.missing_list.charset_list); + +#ifdef notdef + if (oc->core.res_name) + Xfree(oc->core.res_name); + if (oc->core.res_class) + Xfree(oc->core.res_class); +#endif + + Xfree(oc); +} + +static char * +set_oc_values(oc, args, num_args) + XOC oc; + XlcArgList args; + int num_args; +{ + if (oc->core.resources == NULL) + return NULL; + + return _XlcSetValues((XPointer) oc, oc->core.resources, + oc->core.num_resources, args, num_args, XlcSetMask); +} + +static char * +get_oc_values(oc, args, num_args) + XOC oc; + XlcArgList args; + int num_args; +{ + if (oc->core.resources == NULL) + return NULL; + + return _XlcGetValues((XPointer) oc, oc->core.resources, + oc->core.num_resources, args, num_args, XlcGetMask); +} + +static Bool +wcs_to_mbs(oc, to, from, length) + XOC oc; + char *to; + wchar_t *from; + int length; +{ + XlcConv conv = XOC_GENERIC(oc)->wcs_to_cs; + XLCd lcd; + int ret, to_left = length; + + if (conv == NULL) { + lcd = oc->core.om->core.lcd; + conv = _XlcOpenConverter(lcd, XlcNWideChar, lcd, XlcNMultiByte); + if (conv == NULL) + return False; + XOC_GENERIC(oc)->wcs_to_cs = conv; + } else + _XlcResetConverter(conv); + + ret = _XlcConvert(conv, (XPointer *) &from, &length, (XPointer *) &to, + &to_left, NULL, 0); + if (ret != 0 || length > 0) + return False; + + return True; +} + +static int +#if NeedFunctionPrototypes +_XmbDefaultTextEscapement(XOC oc, _Xconst char *text, int length) +#else +_XmbDefaultTextEscapement(oc, text, length) + XOC oc; + char *text; + int length; +#endif +{ + return XTextWidth(*oc->core.font_info.font_struct_list, text, length); +} + +static int +#if NeedFunctionPrototypes +_XwcDefaultTextEscapement(XOC oc, _Xconst wchar_t *text, int length) +#else +_XwcDefaultTextEscapement(oc, text, length) + XOC oc; + wchar_t *text; + int length; +#endif +{ + DefineLocalBuf; + char *buf = AllocLocalBuf(length); + int ret; + + if (buf == NULL) + return 0; + + if (wcs_to_mbs(oc, buf, text, length) == False) + goto err; + + ret = _XmbDefaultTextEscapement(oc, buf, length); + +err: + FreeLocalBuf(buf); + + return ret; +} + +static int +#if NeedFunctionPrototypes +_XmbDefaultTextExtents(XOC oc, _Xconst char *text, int length, + XRectangle *overall_ink, XRectangle *overall_logical) +#else +_XmbDefaultTextExtents(oc, text, length, overall_ink, overall_logical) + XOC oc; + char *text; + int length; + XRectangle *overall_ink; + XRectangle *overall_logical; +#endif +{ + int direction, logical_ascent, logical_descent; + XCharStruct overall; + + XTextExtents(*oc->core.font_info.font_struct_list, text, length, &direction, + &logical_ascent, &logical_descent, &overall); + + if (overall_ink) { + overall_ink->x = overall.lbearing; + overall_ink->y = -(overall.ascent); + overall_ink->width = overall.rbearing - overall.lbearing; + overall_ink->height = overall.ascent + overall.descent; + } + + if (overall_logical) { + overall_logical->x = 0; + overall_logical->y = -(logical_ascent); + overall_logical->width = overall.width; + overall_logical->height = logical_ascent + logical_descent; + } + + return overall.width; +} + +static int +#if NeedFunctionPrototypes +_XwcDefaultTextExtents(XOC oc, _Xconst wchar_t *text, int length, + XRectangle *overall_ink, XRectangle *overall_logical) +#else +_XwcDefaultTextExtents(oc, text, length, overall_ink, overall_logical) + XOC oc; + wchar_t *text; + int length; + XRectangle *overall_ink; + XRectangle *overall_logical; +#endif +{ + DefineLocalBuf; + char *buf = AllocLocalBuf(length); + int ret; + + if (buf == NULL) + return 0; + + if (wcs_to_mbs(oc, buf, text, length) == False) + goto err; + + ret = _XmbDefaultTextExtents(oc, buf, length, overall_ink, overall_logical); + +err: + FreeLocalBuf(buf); + + return ret; +} + +static Status +#if NeedFunctionPrototypes +_XmbDefaultTextPerCharExtents(XOC oc, _Xconst char *text, int length, + XRectangle *ink_buf, XRectangle *logical_buf, + int buf_size, int *num_chars, + XRectangle *overall_ink, + XRectangle *overall_logical) +#else +_XmbDefaultTextPerCharExtents(oc, text, length, ink_buf, logical_buf, buf_size, + num_chars, overall_ink, overall_logical) + XOC oc; + char *text; + int length; + XRectangle *ink_buf; + XRectangle *logical_buf; + int buf_size; + int *num_chars; + XRectangle *overall_ink; + XRectangle *overall_logical; +#endif +{ + XFontStruct *font = *oc->core.font_info.font_struct_list; + XCharStruct *def, *cs, overall; + Bool first = True; + + if (buf_size < length) + return 0; + + bzero((char *) &overall, sizeof(XCharStruct)); + *num_chars = 0; + + CI_GET_DEFAULT_INFO_1D(font, def) + + while (length-- > 0) { + CI_GET_CHAR_INFO_1D(font, *text, def, cs) + text++; + if (cs == NULL) + continue; + + ink_buf->x = overall.width + cs->lbearing; + ink_buf->y = -(cs->ascent); + ink_buf->width = cs->rbearing - cs->lbearing; + ink_buf->height = cs->ascent + cs->descent; + ink_buf++; + + logical_buf->x = overall.width; + logical_buf->y = -(font->ascent); + logical_buf->width = cs->width; + logical_buf->height = font->ascent + font->descent; + logical_buf++; + + if (first) { + overall = *cs; + first = False; + } else { + overall.ascent = max(overall.ascent, cs->ascent); + overall.descent = max(overall.descent, cs->descent); + overall.lbearing = min(overall.lbearing, overall.width + + cs->lbearing); + overall.rbearing = max(overall.rbearing, overall.width + + cs->rbearing); + overall.width += cs->width; + } + (*num_chars)++; + } + + if (overall_ink) { + overall_ink->x = overall.lbearing; + overall_ink->y = -(overall.ascent); + overall_ink->width = overall.rbearing - overall.lbearing; + overall_ink->height = overall.ascent + overall.descent; + } + + if (overall_logical) { + overall_logical->x = 0; + overall_logical->y = -(font->ascent); + overall_logical->width = overall.width; + overall_logical->height = font->ascent + font->descent; + } + + return 1; +} + +static Status +#if NeedFunctionPrototypes +_XwcDefaultTextPerCharExtents(XOC oc, _Xconst wchar_t *text, int length, + XRectangle *ink_buf, XRectangle *logical_buf, + int buf_size, int *num_chars, + XRectangle *overall_ink, + XRectangle *overall_logical) +#else +_XwcDefaultTextPerCharExtents(oc, text, length, ink_buf, logical_buf, buf_size, + num_chars, overall_ink, overall_logical) + XOC oc; + wchar_t *text; + int length; + XRectangle *ink_buf; + XRectangle *logical_buf; + int buf_size; + int *num_chars; + XRectangle *overall_ink; + XRectangle *overall_logical; +#endif +{ + DefineLocalBuf; + char *buf = AllocLocalBuf(length); + Status ret; + + if (buf == NULL) + return 0; + + if (wcs_to_mbs(oc, buf, text, length) == False) + goto err; + + ret = _XmbDefaultTextPerCharExtents(oc, buf, length, ink_buf, logical_buf, + buf_size, num_chars, overall_ink, + overall_logical); + +err: + FreeLocalBuf(buf); + + return ret; +} + +static int +#if NeedFunctionPrototypes +_XmbDefaultDrawString(Display *dpy, Drawable d, XOC oc, GC gc, int x, int y, + _Xconst char *text, int length) +#else +_XmbDefaultDrawString(dpy, d, oc, gc, x, y, text, length) + Display *dpy; + Drawable d; + XOC oc; + GC gc; + int x, y; + char *text; + int length; +#endif +{ + XFontStruct *font = *oc->core.font_info.font_struct_list; + + XSetFont(dpy, gc, font->fid); + XDrawString(dpy, d, gc, x, y, text, length); + + return XTextWidth(font, text, length); +} + +static int +#if NeedFunctionPrototypes +_XwcDefaultDrawString(Display *dpy, Drawable d, XOC oc, GC gc, int x, int y, + _Xconst wchar_t *text, int length) +#else +_XwcDefaultDrawString(dpy, d, oc, gc, x, y, text, length) + Display *dpy; + Drawable d; + XOC oc; + GC gc; + int x, y; + wchar_t *text; + int length; +#endif +{ + DefineLocalBuf; + char *buf = AllocLocalBuf(length); + int ret; + + if (buf == NULL) + return 0; + + if (wcs_to_mbs(oc, buf, text, length) == False) + goto err; + + ret = _XmbDefaultDrawString(dpy, d, oc, gc, x, y, buf, length); + +err: + FreeLocalBuf(buf); + + return ret; +} + +static void +#if NeedFunctionPrototypes +_XmbDefaultDrawImageString(Display *dpy, Drawable d, XOC oc, GC gc, int x, + int y, _Xconst char *text, int length) +#else +_XmbDefaultDrawImageString(dpy, d, oc, gc, x, y, text, length) + Display *dpy; + Drawable d; + XOC oc; + GC gc; + int x, y; + char *text; + int length; +#endif +{ + XSetFont(dpy, gc, (*oc->core.font_info.font_struct_list)->fid); + XDrawImageString(dpy, d, gc, x, y, text, length); +} + +static void +#if NeedFunctionPrototypes +_XwcDefaultDrawImageString(Display *dpy, Drawable d, XOC oc, GC gc, int x, + int y, _Xconst wchar_t *text, int length) +#else +_XwcDefaultDrawImageString(dpy, d, oc, gc, x, y, text, length) + Display *dpy; + Drawable d; + XOC oc; + GC gc; + int x, y; + wchar_t *text; + int length; +#endif +{ + DefineLocalBuf; + char *buf = AllocLocalBuf(length); + + if (buf == NULL) + return; + + if (wcs_to_mbs(oc, buf, text, length) == False) + goto err; + + _XmbDefaultDrawImageString(dpy, d, oc, gc, x, y, buf, length); + +err: + FreeLocalBuf(buf); +} + +static _Xconst XOCMethodsRec oc_default_methods = { + destroy_oc, + set_oc_values, + get_oc_values, + _XmbDefaultTextEscapement, + _XmbDefaultTextExtents, + _XmbDefaultTextPerCharExtents, + _XmbDefaultDrawString, + _XmbDefaultDrawImageString, + _XwcDefaultTextEscapement, + _XwcDefaultTextExtents, + _XwcDefaultTextPerCharExtents, + _XwcDefaultDrawString, + _XwcDefaultDrawImageString +}; + +static XlcResource oc_resources[] = { + { XNBaseFontName, NULLQUARK, sizeof(char *), + XOffsetOf(XOCRec, core.base_name_list), XlcCreateMask | XlcGetMask }, + { XNOMAutomatic, NULLQUARK, sizeof(Bool), + XOffsetOf(XOCRec, core.om_automatic), XlcGetMask }, + { XNMissingCharSet, NULLQUARK, sizeof(XOMCharSetList), + XOffsetOf(XOCRec, core.missing_list), XlcGetMask }, + { XNDefaultString, NULLQUARK, sizeof(char *), + XOffsetOf(XOCRec, core.default_string), XlcGetMask }, + { XNOrientation, NULLQUARK, sizeof(XOrientation), + XOffsetOf(XOCRec, core.orientation), XlcSetMask | XlcGetMask }, + { XNResourceName, NULLQUARK, sizeof(char *), + XOffsetOf(XOCRec, core.res_name), XlcSetMask | XlcGetMask }, + { XNResourceClass, NULLQUARK, sizeof(char *), + XOffsetOf(XOCRec, core.res_class), XlcSetMask | XlcGetMask }, + { XNFontInfo, NULLQUARK, sizeof(XOMFontInfo), + XOffsetOf(XOCRec, core.font_info), XlcGetMask } +}; + +static XOC +create_oc(om, args, num_args) + XOM om; + XlcArgList args; + int num_args; +{ + XOC oc; + XOMGenericPart *gen = XOM_GENERIC(om); + + oc = (XOC) Xmalloc(sizeof(XOCGenericRec)); + if (oc == NULL) + return (XOC) NULL; + bzero((char *) oc, sizeof(XOCGenericRec)); + + oc->core.om = om; + + if (oc_resources[0].xrm_name == NULLQUARK) + _XlcCompileResourceList(oc_resources, XlcNumber(oc_resources)); + + if (_XlcSetValues((XPointer) oc, oc_resources, XlcNumber(oc_resources), + args, num_args, XlcCreateMask | XlcDefaultMask)) + goto err; + + if (oc->core.base_name_list == NULL) + goto err; + + oc->core.resources = oc_resources; + oc->core.num_resources = XlcNumber(oc_resources); + + if (create_fontset(oc) == False) + goto err; + + oc->methods = (XOCMethods)&oc_default_methods; + + return oc; + +err: + destroy_oc(oc); + + return (XOC) NULL; +} + +static Status +close_om(om) + XOM om; +{ + XOMGenericPart *gen = XOM_GENERIC(om); + OMData data; + FontData font_data; + int count; + + if (data = gen->data) { + if (data->font_data) { + for (font_data = data->font_data, count = data->font_data_count; + count-- > 0 ; font_data++) { + if (font_data->name) + Xfree(font_data->name); + } + Xfree(data->font_data); + } + Xfree(gen->data); + } + + if (om->core.res_name) + Xfree(om->core.res_name); + if (om->core.res_class) + Xfree(om->core.res_class); + if (om->core.required_charset.charset_list) + XFreeStringList(om->core.required_charset.charset_list); + else + Xfree((char*)om->core.required_charset.charset_list); + if (om->core.orientation_list.orientation) + Xfree(om->core.orientation_list.orientation); + + Xfree(om); + + return 1; +} + +static char * +set_om_values(om, args, num_args) + XOM om; + XlcArgList args; + int num_args; +{ + if (om->core.resources == NULL) + return NULL; + + return _XlcSetValues((XPointer) om, om->core.resources, + om->core.num_resources, args, num_args, XlcSetMask); +} + +static char * +get_om_values(om, args, num_args) + XOM om; + XlcArgList args; + int num_args; +{ + if (om->core.resources == NULL) + return NULL; + + return _XlcGetValues((XPointer) om, om->core.resources, + om->core.num_resources, args, num_args, XlcGetMask); +} + +static _Xconst XOMMethodsRec methods = { + close_om, + set_om_values, + get_om_values, + create_oc +}; + +static XlcResource om_resources[] = { + { XNRequiredCharSet, NULLQUARK, sizeof(XOMCharSetList), + XOffsetOf(XOMRec, core.required_charset), XlcGetMask }, + { XNQueryOrientation, NULLQUARK, sizeof(XOMOrientation), + XOffsetOf(XOMRec, core.orientation_list), XlcGetMask }, + { XNDirectionalDependentDrawing, NULLQUARK, sizeof(Bool), + XOffsetOf(XOMRec, core.directional_dependent), XlcGetMask }, + { XNContextualDrawing, NULLQUARK, sizeof(Bool), + XOffsetOf(XOMRec, core.contextual_drawing), XlcGetMask } +}; + +static OMData +add_data(om) + XOM om; +{ + XOMGenericPart *gen = XOM_GENERIC(om); + OMData new; + + new = (OMData) Xmalloc(sizeof(OMDataRec)); + + if (new == NULL) + return NULL; + + gen->data = new; + + bzero((char *) new, sizeof(OMDataRec)); + + return new; +} + +static _Xconst char *supported_charset_list[] = { + "ISO8859-1", +/* fix for bug4332979 */ + "adobe-fontspecific", +/* fix for bug4237353: "JISX0201.1976-0" entry should be removed from + supported_charset_list because it is not a supported_charset for C locale + "JISX0201.1976-0", */ + "SUNOLCURSOR-1", + "SUNOLGLYPH-1" +}; + +static Bool +init_om(om) + XOM om; +{ + XLCd lcd = om->core.lcd; + XOMGenericPart *gen = XOM_GENERIC(om); + OMData data; + FontData font_data; + char **required_list; + XOrientation *orientation; + char **value, buf[BUFSIZ], *bufptr; + int count, length = 0; + + value = (char**)supported_charset_list; + count = XlcNumber(supported_charset_list); + + data = add_data(om); + if (data == NULL) + return False; + + font_data = (FontData) Xmalloc(sizeof(FontDataRec) * count); + if (font_data == NULL) + return False; + bzero((char *) font_data, sizeof(FontDataRec) * count); + data->font_data = font_data; + data->font_data_count = count; + + for ( ; count-- > 0; font_data++) { +/* +1266793 +This one is fine. *value points to one of the local strings in +supported_charset_list[]. +*/ + strcpy(buf, *value++); + font_data->name = (char *) Xmalloc(strlen(buf) + 1); + if (font_data->name == NULL) + return False; + strcpy(font_data->name, buf); + } + + length += strlen(data->font_data->name) + 1; + + /* required charset list */ + required_list = (char **) Xmalloc(sizeof(char *)); + if (required_list == NULL) + return False; + + bufptr = (char *) Xmalloc(length); + if (bufptr == NULL) { + Xfree(required_list); + return False; + } + + om->core.required_charset.charset_list = required_list; + om->core.required_charset.charset_count = 1; /* always 1 */ + + data = gen->data; + + strcpy(bufptr, data->font_data->name); + *required_list++ = bufptr; + bufptr += strlen(bufptr) + 1; + + /* orientation list */ + orientation = (XOrientation *) Xmalloc(sizeof(XOrientation)); + if (orientation == NULL) + return False; + + *orientation = XOMOrientation_LTR_TTB; + om->core.orientation_list.orientation = orientation; + om->core.orientation_list.num_orientation = 1; + + /* directional dependent drawing */ + om->core.directional_dependent = False; + + /* contexual drawing */ + om->core.contextual_drawing = False; + + /* context dependent */ + om->core.context_dependent = False; + + return True; +} + +XOM +#if NeedFunctionPrototypes +_XDefaultOpenOM(XLCd lcd, Display *dpy, XrmDatabase rdb, + _Xconst char *res_name, _Xconst char *res_class) +#else +_XDefaultOpenOM(lcd, dpy, rdb, res_name, res_class) +XLCd lcd; +Display *dpy; +XrmDatabase rdb; +char *res_name; +char *res_class; +#endif +{ + XOM om; + + om = (XOM) Xmalloc(sizeof(XOMGenericRec)); + if (om == NULL) + return (XOM) NULL; + bzero((char *) om, sizeof(XOMGenericRec)); + + om->methods = (XOMMethods)&methods; + om->core.lcd = lcd; + om->core.display = dpy; + om->core.rdb = rdb; + if (res_name) { + om->core.res_name = (char *)Xmalloc(strlen(res_name) + 1); + if (om->core.res_name == NULL) + goto err; + strcpy(om->core.res_name, res_name); + } + if (res_class) { + om->core.res_class = (char *)Xmalloc(strlen(res_class) + 1); + if (om->core.res_class == NULL) + goto err; + strcpy(om->core.res_class, res_class); + } + + if (om_resources[0].xrm_name == NULLQUARK) + _XlcCompileResourceList(om_resources, XlcNumber(om_resources)); + + om->core.resources = om_resources; + om->core.num_resources = XlcNumber(om_resources); + + if (init_om(om) == False) + goto err; + + return om; +err: + close_om(om); + + return (XOM) NULL; +} diff --git a/src/xlibi18n/Xaixlcint.h b/src/xlibi18n/Xaixlcint.h new file mode 100644 index 00000000..2e4f3f52 --- /dev/null +++ b/src/xlibi18n/Xaixlcint.h @@ -0,0 +1,54 @@ +/* $Xorg: Xaixlcint.h,v 1.3 2000/08/17 19:45:04 cpqbld Exp $ */ +/* + * + * Copyright IBM Corporation 1993 + * + * All Rights Reserved + * + * License 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 IBM not be + * used in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * + * IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING + * ALL IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS, AND + * NONINFRINGEMENT OF THIRD PARTY RIGHTS, IN NO EVENT SHALL + * IBM 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. + * +*/ +/************************************************************************/ +/* Xaixlcint.h */ +/*----------------------------------------------------------------------*/ +/* This file contains Xlcint.h extension for AIX. */ +/************************************************************************/ +#ifndef _Xaixlcint_h +#define _Xaixlcint_h + +#include "Xlcint.h" +#include <sys/lc_core.h> + +#define _LC_LDX 11 +#define _LC_LDX_R6 (_LC_LDX+1) +#define _LC_VERSION_R5 5 +#define _LC_VERSION_R6 6 + +typedef struct _LC_core_ldx_t { + _LC_object_t lc_object_header; + XLCd (*default_loader)(); + Bool sticky; +} _XlcCoreObjRec, *_XlcCoreObj; + +#if _LC_VERSION < 0x40000000 +#define __type_id type_id +#define __magic magic +#define __version version +#endif + +#endif /*_Xaixlcint_h*/ diff --git a/src/xlibi18n/XimImSw.h b/src/xlibi18n/XimImSw.h new file mode 100644 index 00000000..eac27843 --- /dev/null +++ b/src/xlibi18n/XimImSw.h @@ -0,0 +1,53 @@ +/* $Xorg: XimImSw.h,v 1.3 2000/08/17 19:45:05 cpqbld Exp $ */ +/****************************************************************** + + Copyright 1992, 1993 by FUJITSU LIMITED + +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 FUJITSU LIMITED +not be used in advertising or publicity pertaining to distribution +of the software without specific, written prior permission. +FUJITSU LIMITED makes no representations about the suitability of +this software for any purpose. +It is provided "as is" without express or implied warranty. + +FUJITSU LIMITED DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO +EVENT SHALL FUJITSU LIMITED 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. + + Author: Takashi Fujiwara FUJITSU LIMITED + fujiwara@a80.tech.yk.fujitsu.co.jp + +******************************************************************/ + +#ifndef _XIMIMSW_H +#define _XIMIMSW_H + +typedef struct { + Bool (*checkprocessing)( +#if NeedNestedPrototypes + Xim im +#endif + ); + Bool (*im_open)( +#if NeedNestedPrototypes + Xim im +#endif + ); + void (*im_free)( +#if NeedNestedPrototypes + Xim im +#endif + ); +} XimImsportSW; + +extern XimImsportSW _XimImSportRec[]; + +#endif /* _XIMIMSW_H */ diff --git a/src/xlibi18n/XimProto.h b/src/xlibi18n/XimProto.h new file mode 100644 index 00000000..fe6e5f69 --- /dev/null +++ b/src/xlibi18n/XimProto.h @@ -0,0 +1,227 @@ +/* $Xorg: XimProto.h,v 1.3 2000/08/17 19:45:05 cpqbld Exp $ */ +/****************************************************************** + + Copyright 1992, 1993 by FUJITSU LIMITED + +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 FUJITSU LIMITED +not be used in advertising or publicity pertaining to distribution +of the software without specific, written prior permission. +FUJITSU LIMITED makes no representations about the suitability of +this software for any purpose. +It is provided "as is" without express or implied warranty. + +FUJITSU LIMITED DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO +EVENT SHALL FUJITSU LIMITED 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. + + Author: Takashi Fujiwara FUJITSU LIMITED + fujiwara@a80.tech.yk.fujitsu.co.jp + +******************************************************************/ + +#ifndef _XIMPROTO_H +#define _XIMPROTO_H + +/* + * Default Preconnection selection target + */ +#define XIM_SERVERS "XIM_SERVERS" +#define XIM_LOCALES "LOCALES" +#define XIM_TRANSPORT "TRANSPORT" + +/* + * categories in XIM_SERVERS + */ +#define XIM_SERVER_CATEGORY "@server=" +#define XIM_LOCAL_CATEGORY "@locale=" +#define XIM_TRANSPORT_CATEGORY "@transport=" + +/* + * Xim implementation revision + */ +#define PROTOCOLMAJORVERSION 1 +#define PROTOCOLMINORVERSION 0 + +/* + * Major Protocol number + */ +#define XIM_CONNECT 1 +#define XIM_CONNECT_REPLY 2 +#define XIM_DISCONNECT 3 +#define XIM_DISCONNECT_REPLY 4 + +#define XIM_AUTH_REQUIRED 10 +#define XIM_AUTH_REPLY 11 +#define XIM_AUTH_NEXT 12 +#define XIM_AUTH_SETUP 13 +#define XIM_AUTH_NG 14 + +#define XIM_ERROR 20 + +#define XIM_OPEN 30 +#define XIM_OPEN_REPLY 31 +#define XIM_CLOSE 32 +#define XIM_CLOSE_REPLY 33 +#define XIM_REGISTER_TRIGGERKEYS 34 +#define XIM_TRIGGER_NOTIFY 35 +#define XIM_TRIGGER_NOTIFY_REPLY 36 +#define XIM_SET_EVENT_MASK 37 +#define XIM_ENCODING_NEGOTIATION 38 +#define XIM_ENCODING_NEGOTIATION_REPLY 39 +#define XIM_QUERY_EXTENSION 40 +#define XIM_QUERY_EXTENSION_REPLY 41 +#define XIM_SET_IM_VALUES 42 +#define XIM_SET_IM_VALUES_REPLY 43 +#define XIM_GET_IM_VALUES 44 +#define XIM_GET_IM_VALUES_REPLY 45 + +#define XIM_CREATE_IC 50 +#define XIM_CREATE_IC_REPLY 51 +#define XIM_DESTROY_IC 52 +#define XIM_DESTROY_IC_REPLY 53 +#define XIM_SET_IC_VALUES 54 +#define XIM_SET_IC_VALUES_REPLY 55 +#define XIM_GET_IC_VALUES 56 +#define XIM_GET_IC_VALUES_REPLY 57 +#define XIM_SET_IC_FOCUS 58 +#define XIM_UNSET_IC_FOCUS 59 +#define XIM_FORWARD_EVENT 60 +#define XIM_SYNC 61 +#define XIM_SYNC_REPLY 62 +#define XIM_COMMIT 63 +#define XIM_RESET_IC 64 +#define XIM_RESET_IC_REPLY 65 + +#define XIM_GEOMETRY 70 +#define XIM_STR_CONVERSION 71 +#define XIM_STR_CONVERSION_REPLY 72 +#define XIM_PREEDIT_START 73 +#define XIM_PREEDIT_START_REPLY 74 +#define XIM_PREEDIT_DRAW 75 +#define XIM_PREEDIT_CARET 76 +#define XIM_PREEDIT_CARET_REPLY 77 +#define XIM_PREEDIT_DONE 78 +#define XIM_STATUS_START 79 +#define XIM_STATUS_DRAW 80 +#define XIM_STATUS_DONE 81 +#define XIM_PREEDITSTATE 82 + +/* + * values for the flag of XIM_ERROR + */ +#define XIM_IMID_VALID 0x0001 +#define XIM_ICID_VALID 0x0002 + +/* + * XIM Error Code + */ +#define XIM_BadAlloc 1 +#define XIM_BadStyle 2 +#define XIM_BadClientWindow 3 +#define XIM_BadFocusWindow 4 +#define XIM_BadArea 5 +#define XIM_BadSpotLocation 6 +#define XIM_BadColormap 7 +#define XIM_BadAtom 8 +#define XIM_BadPixel 9 +#define XIM_BadPixmap 10 +#define XIM_BadName 11 +#define XIM_BadCursor 12 +#define XIM_BadProtocol 13 +#define XIM_BadForeground 14 +#define XIM_BadBackground 15 +#define XIM_LocaleNotSupported 16 +#define XIM_BadSomething 999 + +/* + * byte order + */ +#define BIGENDIAN (CARD8)0x42 /* MSB first */ +#define LITTLEENDIAN (CARD8)0x6c /* LSB first */ + +/* + * values for the type of XIMATTR & XICATTR + */ +#define XimType_SeparatorOfNestedList 0 +#define XimType_CARD8 1 +#define XimType_CARD16 2 +#define XimType_CARD32 3 +#define XimType_STRING8 4 +#define XimType_Window 5 +#define XimType_XIMStyles 10 +#define XimType_XRectangle 11 +#define XimType_XPoint 12 +#define XimType_XFontSet 13 +#define XimType_XIMOptions 14 +#define XimType_XIMHotKeyTriggers 15 +#define XimType_XIMHotKeyState 16 +#define XimType_XIMStringConversion 17 +#define XimType_NEST 0x7fff + +/* + * values for the category of XIM_ENCODING_NEGITIATON_REPLY + */ +#define XIM_Encoding_NameCategory 0 +#define XIM_Encoding_DetailCategory 1 + +/* + * value for the index of XIM_ENCODING_NEGITIATON_REPLY + */ +#define XIM_Default_Encoding_IDX -1 + +/* + * value for the flag of XIM_FORWARD_EVENT, XIM_COMMIT + */ +#define XimSYNCHRONUS 0x0001 +#define XimLookupChars 0x0002 +#define XimLookupKeySym 0x0004 +#define XimLookupBoth 0x0006 + +/* + * request packet header size + */ +#define XIM_HEADER_SIZE \ + sizeof(CARD8) /* sizeof mejor-opcode */ \ + + sizeof(CARD8) /* sizeof minor-opcode */ \ + + sizeof(INT16) /* sizeof length */ + +/* + * Client Message data size + */ +#define XIM_CM_DATA_SIZE 20 + +/* + * XIM data structure + */ +typedef CARD16 BITMASK16; +typedef CARD32 BITMASK32; +typedef CARD32 EVENTMASK; + +typedef CARD16 XIMID; /* Input Method ID */ +typedef CARD16 XICID; /* Input Context ID */ + +/* + * Padding macro + */ +#define XIM_PAD(length) ((4 - ((length) % 4)) % 4) + +#define XIM_SET_PAD(ptr, length) \ + { \ + register int Counter = XIM_PAD((int)length); \ + if (Counter) { \ + register char *Ptr = (char *)(ptr) + (length); \ + length += Counter; \ + for (; Counter; --Counter, ++Ptr) \ + *Ptr = '\0'; \ + } \ + } + +#endif /* _XIMPROTO_H */ diff --git a/src/xlibi18n/XimThai.h b/src/xlibi18n/XimThai.h new file mode 100644 index 00000000..b883a6ef --- /dev/null +++ b/src/xlibi18n/XimThai.h @@ -0,0 +1,201 @@ +/* $Xorg: XimThai.h,v 1.4 2001/02/09 02:03:38 xorgcvs Exp $ */ +/*********************************************************** + +Copyright 1993, 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 1993 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. + +******************************************************************/ + +/* +**++ +** FACILITY: +** +** Xlib +** +** ABSTRACT: +** +** Definition file for Thai specific functions. +** +** MODIFICATION HISTORY: +** +**/ + +#ifndef _XIMTHAI_H_ +#define _XIMTHAI_H_ + +#include <X11/Xlib.h> + +/* Classification of characters in TACTIS according to WTT */ + +#define CTRL 0 /* control chars */ +#define NON 1 /* non composibles */ +#define CONS 2 /* consonants */ +#define LV 3 /* leading vowels */ +#define FV1 4 /* following vowels */ +#define FV2 5 +#define FV3 6 +#define BV1 7 /* below vowels */ +#define BV2 8 +#define BD 9 /* below diacritics */ +#define TONE 10 /* tonemarks */ +#define AD1 11 /* above diacritics */ +#define AD2 12 +#define AD3 13 +#define AV1 14 /* above vowels */ +#define AV2 15 +#define AV3 16 + + +/* extended classification */ + +#define DEAD 17 /* group of non-spacing characters */ + + +/* display levels in display cell */ + +#define NONDISP 0 /* non displayable */ +#define TOP 1 +#define ABOVE 2 +#define BASE 3 +#define BELOW 4 + + +/* Input Sequence Check modes */ + +#define WTT_ISC1 1 /* WTT default ISC mode */ +#define WTT_ISC2 2 /* WTT strict ISC mode */ +#define THAICAT_ISC 3 /* THAICAT ISC mode */ +#define NOISC 255 /* No ISC */ + + +/* Function prototypes (thaisub.c) */ + +Private +int THAI_chtype ( /* returns classification of a char */ +#if NeedFunctionPrototypes + unsigned char ch +#endif +); + +Private +int THAI_chlevel ( /* returns the display level */ +#if NeedFunctionPrototypes + unsigned char ch +#endif +); + +Private +Bool THAI_isdead ( /* return True if char is non-spacing */ +#if NeedFunctionPrototypes + unsigned char ch +#endif +); + +Private +Bool THAI_iscons ( /* return True if char is consonant */ +#if NeedFunctionPrototypes + unsigned char ch +#endif +); + +Private +Bool THAI_isvowel ( /* return True if char is vowel */ +#if NeedFunctionPrototypes + unsigned char ch +#endif +); + +Private +Bool THAI_istone ( /* return True if char is tonemark */ +#if NeedFunctionPrototypes + unsigned char ch +#endif +); + +Private +Bool THAI_iscomposible ( +#if NeedFunctionPrototypes + unsigned char follow_ch, + unsigned char lead_ch +#endif +); + +Private +Bool THAI_isaccepted ( +#if NeedFunctionPrototypes + unsigned char follow_ch, + unsigned char lead_ch, + unsigned char isc_mode +#endif +); + +Private +void THAI_apply_write_rules ( +#if NeedFunctionPrototypes + unsigned char *instr, + unsigned char *outstr, + unsigned char insert_ch, + int *num_insert_ch +#endif +); + +Private +int THAI_find_chtype ( +#if NeedFunctionPrototypes + unsigned char *instr, + int chtype +#endif +); + +Private +int THAI_apply_scm ( +#if NeedFunctionPrototypes + unsigned char *instr, + unsigned char *outstr, + unsigned char spec_ch, + int num_sp, + unsigned char insert_ch +#endif +); + +#endif /* _XIMTHAI_H_ */ diff --git a/src/xlibi18n/XimTrInt.h b/src/xlibi18n/XimTrInt.h new file mode 100644 index 00000000..b10898b3 --- /dev/null +++ b/src/xlibi18n/XimTrInt.h @@ -0,0 +1,73 @@ +/* $Xorg: XimTrInt.h,v 1.3 2000/08/17 19:45:05 cpqbld Exp $ */ +/****************************************************************** + + Copyright 1992 by Sun Microsystems, Inc. + Copyright 1993, 1994 by FUJITSU LIMITED + +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 Sun Microsystems, Inc. +not be used in advertising or publicity pertaining to distribution +of the software without specific, written prior permission. +Sun Microsystems, Inc. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without +express or implied warranty. + +Sun Microsystems Inc. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS +SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, +IN NO EVENT SHALL Sun Microsystems, Inc. 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. + + Author: Hideki Hiura (hhiura@Sun.COM) Sun Microsystems, Inc. + Takashi Fujiwara FUJITSU LIMITED + fujiwara@a80.tech.yk.fujitsu.co.jp + +******************************************************************/ + +#ifndef _XIMTRINT_H +#define _XIMTRINT_H + +#if NeedFunctionPrototypes +#include "Ximint.h" +#endif + +typedef struct { + char *transportname; + Bool (*config)( +#if NeedFunctionPrototypes + Xim, + char * +#endif + ); +} TransportSW; + +extern TransportSW _XimTransportRec[]; + +/* + * Global symbols + */ + +extern Bool _XimXConf( +#if NeedFunctionPrototypes + Xim im, + char *address +#endif +); + +#if defined(TCPCONN) || defined(UNIXCONN) || defined(DNETCONN) || defined(STREAMSCONN) + +extern Bool _XimTransConf( +#if NeedFunctionPrototypes + Xim im, + char *address +#endif +); + +#endif + +#endif /* _XIMTRINT_H */ diff --git a/src/xlibi18n/XimTrX.h b/src/xlibi18n/XimTrX.h new file mode 100644 index 00000000..489a0e3c --- /dev/null +++ b/src/xlibi18n/XimTrX.h @@ -0,0 +1,67 @@ +/* $Xorg: XimTrX.h,v 1.3 2000/08/17 19:45:05 cpqbld Exp $ */ +/****************************************************************** + + Copyright 1992 by Sun Microsystems, Inc. + Copyright 1992, 1993, 1994 by FUJITSU LIMITED + +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 Sun Microsystems, Inc. +and FUJITSU LIMITED not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior permission. +Sun Microsystems, Inc. and FUJITSU LIMITED makes no representations about +the suitability of this software for any purpose. +It is provided "as is" without express or implied warranty. + +Sun Microsystems Inc. AND FUJITSU LIMITED DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS, IN NO EVENT SHALL Sun Microsystems, Inc. AND FUJITSU LIMITED +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. + + Author: Hideki Hiura (hhiura@Sun.COM) Sun Microsystems, Inc. + Takashi Fujiwara FUJITSU LIMITED + fujiwara@a80.tech.yk.fujitsu.co.jp + +******************************************************************/ + +#ifndef _XIMTRX_H +#define _XIMTRX_H + +typedef struct _XIntrCallbackRec *XIntrCallbackPtr; + +typedef struct _XIntrCallbackRec { + Bool (*func)( +#if NeedNestedPrototypes + Xim, INT16, XPointer, XPointer +#endif +); + XPointer call_data; + XIntrCallbackPtr next; +} XIntrCallbackRec ; + +typedef struct _XSpecRec { + XIntrCallbackPtr intr_cb; + Atom imconnectid; + Atom improtocolid; + Atom immoredataid; + Window lib_connect_wid; + Window ims_connect_wid; + XPointer ev; + CARD32 major_code; + CARD32 minor_code; + CARD32 BoundarySize; +} XSpecRec; + +#define _XIM_PROTOCOL "_XIM_PROTOCOL" +#define _XIM_XCONNECT "_XIM_XCONNECT" +#define _XIM_MOREDATA "_XIM_MOREDATA" + +#define MAJOR_TRANSPORT_VERSION 0 +#define MINOR_TRANSPORT_VERSION 0 + +#endif /* _XIMTRX_H */ diff --git a/src/xlibi18n/XimTrans.h b/src/xlibi18n/XimTrans.h new file mode 100644 index 00000000..6914190e --- /dev/null +++ b/src/xlibi18n/XimTrans.h @@ -0,0 +1,127 @@ +/* $Xorg: XimTrans.h,v 1.3 2000/08/17 19:45:05 cpqbld Exp $ */ +/****************************************************************** + + Copyright 1992 by Sun Microsystems, Inc. + Copyright 1992, 1993, 1994 by FUJITSU LIMITED + +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 Sun Microsystems, Inc. +and FUJITSU LIMITED not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior permission. +Sun Microsystems, Inc. and FUJITSU LIMITED makes no representations about +the suitability of this software for any purpose. +It is provided "as is" without express or implied warranty. + +Sun Microsystems Inc. AND FUJITSU LIMITED DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS, IN NO EVENT SHALL Sun Microsystems, Inc. AND FUJITSU LIMITED +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. + + Author: Hideki Hiura (hhiura@Sun.COM) Sun Microsystems, Inc. + Takashi Fujiwara FUJITSU LIMITED + fujiwara@a80.tech.yk.fujitsu.co.jp + +******************************************************************/ + +#ifndef _XIMTRANS_H +#define _XIMTRANS_H + +typedef struct _TransIntrCallbackRec *TransIntrCallbackPtr; + +typedef struct _TransIntrCallbackRec { + Bool (*func)( +#if NeedNestedPrototypes + Xim, INT16, XPointer, XPointer +#endif + ); + XPointer call_data; + TransIntrCallbackPtr next; +} TransIntrCallbackRec ; + +typedef struct { + TransIntrCallbackPtr intr_cb; + struct _XtransConnInfo *trans_conn; /* transport connection object */ + int fd; + char *address; + Window window; + Bool is_putback; +} TransSpecRec; + + +/* + * Prototypes + */ + +extern Bool _XimTransIntrCallback( +#if NeedFunctionPrototypes + Xim im, + Bool (*callback)( +#if NeedNestedPrototypes + Xim, INT16, XPointer, XPointer +#endif + ), + XPointer call_data +#endif +); + +extern void _XimFreeTransIntrCallback( +#if NeedFunctionPrototypes + Xim im +#endif +); + +extern Bool _XimTransIntrCallbackCheck( +#if NeedFunctionPrototypes + Xim im, + INT16 len, + XPointer data +#endif +); + +extern Bool _XimTransFilterWaitEvent( +#if NeedFunctionPrototypes + Display *d, + Window w, + XEvent *ev, + XPointer arg +#endif +); + +extern void _XimTransInternalConnection( +#if NeedFunctionPrototypes + Display *d, + int fd, + XPointer arg +#endif +); + +extern Bool _XimTransWrite( +#if NeedFunctionPrototypes + Xim im, + INT16 len, + XPointer data +#endif +); + +extern Bool _XimTransRead( +#if NeedFunctionPrototypes + Xim im, + XPointer recv_buf, + int buf_len, + int *ret_len +#endif +); + +extern void _XimTransFlush( +#if NeedFunctionPrototypes + Xim im +#endif +); + +#endif /* _XIMTRANS__H */ diff --git a/src/xlibi18n/Ximint.h b/src/xlibi18n/Ximint.h new file mode 100644 index 00000000..17ca94a0 --- /dev/null +++ b/src/xlibi18n/Ximint.h @@ -0,0 +1,1144 @@ +/* $Xorg: Ximint.h,v 1.3 2000/08/17 19:45:05 cpqbld Exp $ */ +/****************************************************************** + + Copyright 1992, 1993, 1994 by FUJITSU LIMITED + Copyright 1993, 1994 by Sony Corporation + +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 FUJITSU LIMITED and +Sony Corporation not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. FUJITSU LIMITED and Sony Corporation makes no +representations about the suitability of this software for any +purpose. It is provided "as is" without express or implied warranty. + +FUJITSU LIMITED AND SONY CORPORATION DISCLAIM ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL FUJITSU LIMITED AND +SONY CORPORATION 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. + + Author: Takashi Fujiwara FUJITSU LIMITED + fujiwara@a80.tech.yk.fujitsu.co.jp + Motifier: Makoto Wakamatsu Sony Corporation + makoto@sm.sony.co.jp + +******************************************************************/ + +#ifndef _XIMINT_H +#define _XIMINT_H + +#include <stdio.h> +#include <X11/Xutil.h> + +#define Public /**/ +#define Private static + +typedef struct _Xim *Xim; +typedef struct _Xic *Xic; + +/* + * Input Method data + */ +#include "XimintP.h" +#include "XimintL.h" + +/* + * XIM dependent data + */ +typedef union _XIMPrivateRec { + XimLocalPrivateRec local; + XimProtoPrivateRec proto; +} XIMPrivateRec; + +/* + * IM struct + */ +typedef struct _Xim { + XIMMethods methods; + XIMCoreRec core; + XIMPrivateRec private; +} XimRec; + +/* + * IC deprndent data + */ +typedef union _XICPrivateRec { + XicLocalPrivateRec local; + XicProtoPrivateRec proto; +} XICPrivateRec; + +/* + * IC struct + */ +typedef struct _Xic { + XICMethods methods; + XICCoreRec core; + XICPrivateRec private; +} XicRec; + +typedef struct _XimDefIMValues { + XIMValuesList *im_values_list; + XIMValuesList *ic_values_list; + XIMStyles *styles; + XIMCallback destroy_callback; + char *res_name; + char *res_class; + Bool visible_position; +} XimDefIMValues; + +typedef struct _XimDefICValues { + XIMStyle input_style; + Window client_window; + Window focus_window; + unsigned long filter_events; + XIMCallback geometry_callback; + char *res_name; + char *res_class; + XIMCallback destroy_callback; + XIMCallback preedit_state_notify_callback; + XIMCallback string_conversion_callback; + XIMStringConversionText string_conversion; + XIMResetState reset_state; + XIMHotKeyTriggers *hotkey; + XIMHotKeyState hotkey_state; + ICPreeditAttributes preedit_attr; + ICStatusAttributes status_attr; +} XimDefICValues; + +#define XIM_MODE_IM_GET (1 << 0) +#define XIM_MODE_IM_SET (1 << 1) +#define XIM_MODE_IM_DEFAULT (1 << 2) + +#define XIM_MODE_PRE_GET (1 << 0) +#define XIM_MODE_PRE_SET (1 << 1) +#define XIM_MODE_PRE_CREATE (1 << 2) +#define XIM_MODE_PRE_ONCE (1 << 3) +#define XIM_MODE_PRE_DEFAULT (1 << 4) + +#define XIM_MODE_STS_GET (1 << 5) +#define XIM_MODE_STS_SET (1 << 6) +#define XIM_MODE_STS_CREATE (1 << 7) +#define XIM_MODE_STS_ONCE (1 << 8) +#define XIM_MODE_STS_DEFAULT (1 << 9) + +#define XIM_MODE_IC_GET (XIM_MODE_PRE_GET | XIM_MODE_STS_GET) +#define XIM_MODE_IC_SET (XIM_MODE_PRE_SET | XIM_MODE_STS_SET) +#define XIM_MODE_IC_CREATE (XIM_MODE_PRE_CREATE | XIM_MODE_STS_CREATE) +#define XIM_MODE_IC_ONCE (XIM_MODE_PRE_ONCE | XIM_MODE_STS_ONCE) +#define XIM_MODE_IC_DEFAULT (XIM_MODE_PRE_DEFAULT | XIM_MODE_STS_DEFAULT) + +#define XIM_MODE_PRE_MASK (XIM_MODE_PRE_GET | XIM_MODE_PRE_SET | \ + XIM_MODE_PRE_CREATE | XIM_MODE_PRE_ONCE | \ + XIM_MODE_PRE_DEFAULT) +#define XIM_MODE_STS_MASK (XIM_MODE_STS_GET | XIM_MODE_STS_SET | \ + XIM_MODE_STS_CREATE | XIM_MODE_STS_ONCE | \ + XIM_MODE_STS_DEFAULT) + +#define XIM_SETIMDEFAULTS (1L << 0) +#define XIM_SETIMVALUES (1L << 1) +#define XIM_GETIMVALUES (1L << 2) + +#define XIM_SETICDEFAULTS (1L << 0) +#define XIM_CREATEIC (1L << 1) +#define XIM_SETICVALUES (1L << 2) +#define XIM_GETICVALUES (1L << 3) +#define XIM_PREEDIT_ATTR (1L << 4) +#define XIM_STATUS_ATTR (1L << 5) + +#define XIM_CHECK_VALID 0 +#define XIM_CHECK_INVALID 1 +#define XIM_CHECK_ERROR 2 + +#define FILTERD True +#define NOTFILTERD False + +#define XIMMODIFIER "@im=" + +#define XIM_TRUE True +#define XIM_FALSE False +#define XIM_OVERFLOW (-1) + +/* + * Global symbols + */ + +extern Bool _XimSetIMResourceList( +#if NeedFunctionPrototypes + XIMResourceList *res_list, + unsigned int *list_num +#endif +); + +extern Bool _XimSetICResourceList( +#if NeedFunctionPrototypes + XIMResourceList *res_list, + unsigned int *list_num +#endif +); + +extern Bool _XimSetInnerIMResourceList( +#if NeedFunctionPrototypes + XIMResourceList *res_list, + unsigned int *list_num +#endif +); + +extern Bool _XimSetInnerICResourceList( +#if NeedFunctionPrototypes + XIMResourceList *res_list, + unsigned int *list_num +#endif +); + +extern Bool cw_XimCheckCreateICValues( +#if NeedFunctionPrototypes + XIMResourceList res_list, + unsigned int list_num +#endif +); + +extern XIMResourceList _XimGetResourceListRec( +#if NeedFunctionPrototypes + XIMResourceList res_list, + unsigned int list_num, + char *name +#endif +); + +extern void _XimSetIMMode( +#if NeedFunctionPrototypes + XIMResourceList res_list, + unsigned int list_num +#endif +); + +extern void _XimSetICMode( +#if NeedFunctionPrototypes + XIMResourceList res_list, + unsigned int list_num, + XIMStyle style +#endif +); + +extern int _XimCheckIMMode( +#if NeedFunctionPrototypes + XIMResourceList res_list, + unsigned long mode +#endif +); + +extern int _XimCheckICMode( +#if NeedFunctionPrototypes + XIMResourceList res_list, + unsigned long mode +#endif +); + +extern Bool _XimSetLocalIMDefaults( +#if NeedFunctionPrototypes + Xim im, + XPointer top, + XIMResourceList res_list, + unsigned int list_num +#endif +); + +extern Bool _XimSetICDefaults( +#if NeedFunctionPrototypes + Xic ic, + XPointer top, + unsigned long mode, + XIMResourceList res_list, + unsigned int list_num +#endif +); + +extern Bool _XimEncodeLocalIMAttr( +#if NeedFunctionPrototypes + XIMResourceList res, + XPointer top, + XPointer val +#endif +); + +extern Bool _XimEncodeLocalICAttr( +#if NeedFunctionPrototypes + Xic ic, + XIMResourceList res, + XPointer top, + XIMArg *arg, + unsigned long mode +#endif +); + +extern Bool _XimCheckLocalInputStyle( +#if NeedFunctionPrototypes + Xic ic, + XPointer top, + XIMArg *values, + XIMStyles *styles, + XIMResourceList res_list, + unsigned int list_num +#endif +); + +extern Bool _XimDecodeLocalIMAttr( +#if NeedFunctionPrototypes + XIMResourceList res, + XPointer top, + XPointer val +#endif +); + +extern Bool _XimDecodeLocalICAttr( +#if NeedFunctionPrototypes + XIMResourceList res, + XPointer top, + XPointer val, + unsigned long mode +#endif +); + +extern void _XimGetCurrentIMValues( +#if NeedFunctionPrototypes + Xim im, + XimDefIMValues *im_values +#endif +); + +extern void _XimSetCurrentIMValues( +#if NeedFunctionPrototypes + Xim im, + XimDefIMValues *im_values +#endif +); + +extern void _XimGetCurrentICValues( +#if NeedFunctionPrototypes + Xic ic, + XimDefICValues *ic_values +#endif +); + +extern void _XimSetCurrentICValues( +#if NeedFunctionPrototypes + Xic ic, + XimDefICValues *ic_values +#endif +); + +extern void _XimInitialResourceInfo( +#if NeedFunctionPrototypes + void +#endif +); + +extern void _XimParseStringFile( +#if NeedFunctionPrototypes + FILE *fp, + DefTree **ptop +#endif +); + +extern Bool _XimCheckIfLocalProcessing( +#if NeedFunctionPrototypes + Xim im +#endif +); + +extern Bool _XimCheckIfThaiProcessing( +#if NeedFunctionPrototypes + Xim im +#endif +); + +extern Bool _XimLocalOpenIM( +#if NeedFunctionPrototypes + Xim im +#endif +); + +extern Bool _XimThaiOpenIM( +#if NeedFunctionPrototypes + Xim im +#endif +); + +extern Bool _XimProtoOpenIM( +#if NeedFunctionPrototypes + Xim im +#endif +); + +extern void _XimLocalIMFree( +#if NeedFunctionPrototypes + Xim im +#endif +); + +extern void _XimThaiIMFree( +#if NeedFunctionPrototypes + Xim im +#endif +); + +extern void _XimProtoIMFree( +#if NeedFunctionPrototypes + Xim im +#endif +); + +extern char * _XimSetIMValueData( +#if NeedFunctionPrototypes + Xim im, + XPointer top, + XIMArg *arg, + XIMResourceList res_list, + unsigned int list_num +#endif +); + +extern char * _XimGetIMValueData( +#if NeedFunctionPrototypes + Xim im, + XPointer top, + XIMArg *arg, + XIMResourceList res_list, + unsigned int list_num +#endif +); + +extern char * _XimSetICValueData( +#if NeedFunctionPrototypes + Xic ic, + XPointer top, + XIMResourceList res_list, + unsigned int list_num, + XIMArg *arg, + unsigned long mode, + Bool flag +#endif +); + +extern char * _XimGetICValueData( +#if NeedFunctionPrototypes + Xic ic, + XPointer top, + XIMResourceList res_list, + unsigned int list_num, + XIMArg *arg, + unsigned long mode +#endif +); + +extern char * _XimLocalSetIMValues( +#if NeedFunctionPrototypes + XIM im, + XIMArg *arg +#endif +); + +extern char * _XimLocalGetIMValues( +#if NeedFunctionPrototypes + XIM im, + XIMArg *arg +#endif +); + +extern XIC _XimLocalCreateIC( +#if NeedFunctionPrototypes + XIM im, + XIMArg *arg +#endif +); + +extern Bool _XimDispatchInit( +#if NeedFunctionPrototypes + Xim im +#endif +); + +extern Bool _XimGetAttributeID( +#if NeedFunctionPrototypes + Xim im, + CARD16 *buf +#endif +); + +extern Bool _XimExtension( +#if NeedFunctionPrototypes + Xim im +#endif +); + +extern void _XimDestroyIMStructureList( +#if NeedFunctionPrototypes + Xim im +#endif +); + +extern char * _XimMakeIMAttrIDList( +#if NeedFunctionPrototypes + Xim im, + XIMResourceList res_list, + unsigned int res_num, + XIMArg *arg, + CARD16 *buf, + INT16 *len, + unsigned long mode +#endif +); + +extern char * _XimMakeICAttrIDList( +#if NeedFunctionPrototypes + Xic ic, + XIMResourceList res_list, + unsigned int res_num, + XIMArg *arg, + CARD16 *idList, + INT16 *num, + unsigned long mode +#endif +); + +extern char * _XimDecodeIMATTRIBUTE( +#if NeedFunctionPrototypes + Xim im, + XIMResourceList res_list, + unsigned int res_num, + CARD16 *buf, + INT16 buf_len, + XIMArg *arg, + BITMASK32 mode +#endif +); + +extern char * _XimDecodeICATTRIBUTE( +#if NeedFunctionPrototypes + Xic ic, + XIMResourceList res_list, + unsigned int res_num, + CARD16 *buf, + INT16 buf_len, + XIMArg *arg, + BITMASK32 mode +#endif +); + +extern Bool _XimRegProtoIntrCallback( +#if NeedFunctionPrototypes + Xim im, + CARD16 major_code, + CARD16 minor_code, + Bool (*proc)( +#if NeedNestedPrototypes + Xim, INT16, XPointer, XPointer +#endif + ), + XPointer call_data +#endif +); + +extern Bool _XimErrorCallback( +#if NeedFunctionPrototypes + Xim im, + INT16 len, + XPointer data, + XPointer call_data +#endif +); + +extern Bool _XimRegisterTriggerKeysCallback( +#if NeedFunctionPrototypes + Xim im, + INT16 len, + XPointer data, + XPointer call_data +#endif +); + +extern Bool _XimSetEventMaskCallback( +#if NeedFunctionPrototypes + Xim im, + INT16 len, + XPointer data, + XPointer call_data +#endif +); + +extern Bool _XimForwardEventCallback( +#if NeedFunctionPrototypes + Xim im, + INT16 len, + XPointer data, + XPointer call_data +#endif +); + +extern Bool _XimCommitCallback( +#if NeedFunctionPrototypes + Xim im, + INT16 len, + XPointer data, + XPointer call_data +#endif +); + +extern Bool _XimSyncCallback( +#if NeedFunctionPrototypes + Xim im, + INT16 len, + XPointer data, + XPointer call_data +#endif +); + +extern void _XimFreeProtoIntrCallback( +#if NeedFunctionPrototypes + Xim im +#endif +); + +extern XIC _XimProtoCreateIC( +#if NeedFunctionPrototypes + XIM im, + XIMArg *arg +#endif +); + +extern void _XimRegisterServerFilter( +#if NeedFunctionPrototypes + Xim im +#endif +); + +extern void _XimUnregisterServerFilter( +#if NeedFunctionPrototypes + Xim im +#endif +); + +extern Bool _XimTriggerNotify( +#if NeedFunctionPrototypes + Xim im, + Xic ic, + int mode, + CARD32 idx +#endif +); + +extern Bool _XimProcSyncReply( +#if NeedFunctionPrototypes + Xim im, + Xic ic +#endif +); + +extern void _XimSendSetFocus( +#if NeedFunctionPrototypes + Xim im, + Xic ic +#endif +); + +extern Bool _XimForwardEvent( +#if NeedFunctionPrototypes + Xic ic, + XEvent *ev, + Bool sync +#endif +); + +extern void _XimFreeRemakeArg( +#if NeedFunctionPrototypes + XIMArg *arg +#endif +); + +extern void _XimServerDestroy( +#if NeedFunctionPrototypes + Xim im +#endif +); + +extern char * _XimEncodeIMATTRIBUTE( +#if NeedFunctionPrototypes + Xim im, + XIMResourceList res_list, + unsigned int res_num, + XIMArg *arg, + XIMArg **arg_ret, + char *buf, + int size, + int *ret_len, + XPointer top, + unsigned long mode +#endif +); + +extern char * _XimEncodeICATTRIBUTE( +#if NeedFunctionPrototypes + Xic ic, + XIMResourceList res_list, + unsigned int res_num, + XIMArg *arg, + XIMArg **arg_ret, + char *buf, + int size, + int *ret_len, + XPointer top, + BITMASK32 *flag, + unsigned long mode +#endif +); + +#ifdef EXT_MOVE +extern Bool _XimExtenMove( +#if NeedFunctionPrototypes + Xim im, + Xic ic, + CARD32 flag, + CARD16 *buf, + INT16 length +#endif +); +#endif + +extern int _Ximctstombs( +#if NeedFunctionPrototypes + XIM im, + char *from, + int from_len, + char *to, + int to_len, + Status *state +#endif +); + +extern int _Ximctstowcs( +#if NeedFunctionPrototypes + XIM im, + char *from, + int from_len, + wchar_t *to, + int to_len, + Status *state +#endif +); + +extern int _XimLcctstombs( +#if NeedFunctionPrototypes + XIM im, + char *from, + int from_len, + char *to, + int to_len, + Status *state +#endif +); + +extern int _XimLcctstowcs( +#if NeedFunctionPrototypes + XIM im, + char *from, + int from_len, + wchar_t *to, + int to_len, + Status *state +#endif +); + +extern void _XimSetHeader( +#if NeedFunctionPrototypes + XPointer buf, + CARD8 major_opcode, + CARD8 minor_opcode, + INT16 *len +#endif +); + +extern Bool _XimSync( +#if NeedFunctionPrototypes + Xim im, + Xic ic +#endif +); + +extern int _XimProtoMbLookupString( +#if NeedFunctionPrototypes + XIC xic, + XKeyEvent *ev, + char *buffer, + int bytes, + KeySym *keysym, + Status *state +#endif +); + +extern int _XimProtoWcLookupString( +#if NeedFunctionPrototypes + XIC xic, + XKeyEvent *ev, + wchar_t *buffer, + int bytes, + KeySym *keysym, + Status *state +#endif +); + +extern void _XimRegisterFilter( +#if NeedFunctionPrototypes + Xic ic +#endif +); + +extern void _XimUnregisterFilter( +#if NeedFunctionPrototypes + Xic ic +#endif +); + +extern void _XimReregisterFilter( +#if NeedFunctionPrototypes + Xic ic +#endif +); + +extern Status _XimProtoEventToWire( +#if NeedFunctionPrototypes + XEvent *re, + xEvent *event, + Bool sw +#endif +); + +extern Bool _XimProtoWireToEvent( +#if NeedFunctionPrototypes + XEvent *re, + xEvent *event, + Bool sw +#endif +); + +#ifdef EXT_FORWARD +extern Bool _XimExtForwardKeyEvent( +#if NeedFunctionPrototypes + Xic ic, + XKeyEvent *ev, + Bool sync +#endif +); +#endif + +extern int _XimLookupMBText( +#if NeedFunctionPrototypes + Xic ic, + XKeyEvent *event, + char *buffer, + int nbytes, + KeySym *keysym, + XComposeStatus *status +#endif +); + +extern int _XimLookupWCText( +#if NeedFunctionPrototypes + Xic ic, + XKeyEvent *event, + wchar_t *buffer, + int nbytes, + KeySym *keysym, + XComposeStatus *status +#endif +); + +extern EVENTMASK _XimGetWindowEventmask( +#if NeedFunctionPrototypes + Xic ic +#endif +); + +extern Xic _XimICOfXICID( +#if NeedFunctionPrototypes + Xim im, + XICID icid +#endif +); + +extern void _XimResetIMInstantiateCallback( +#if NeedFunctionPrototypes + Xim xim +#endif +); + +extern Bool _XimRegisterIMInstantiateCallback( +#if NeedFunctionPrototypes + XLCd lcd, + Display *display, + XrmDatabase rdb, + char *res_name, + char *res_class, + XIMProc callback, + XPointer *client_data +#endif +); + +extern Bool _XimUnRegisterIMInstantiateCallback( +#if NeedFunctionPrototypes + XLCd lcd, + Display *display, + XrmDatabase rdb, + char *res_name, + char *res_class, + XIMProc callback, + XPointer *client_data +#endif +); + +extern void _XimFreeCommitInfo( +#if NeedFunctionPrototypes + Xic ic +#endif +); + +extern Bool _XimConnect( +#if NeedFunctionPrototypes + Xim im +#endif +); + +extern Bool _XimShutdown( +#if NeedFunctionPrototypes + Xim im +#endif +); + +extern Bool _XimWrite( +#if NeedFunctionPrototypes + Xim im, + INT16 len, + XPointer data +#endif +); + +extern Bool _XimRead( +#if NeedFunctionPrototypes + Xim im, + INT16 *len, + XPointer data, + int data_len, + Bool (*predicate)( +#if NeedNestedPrototypes + Xim, INT16, XPointer, XPointer +#endif + ), + XPointer arg +#endif +); + +extern Bool _XimIntrCallback( +#if NeedFunctionPrototypes + Xim im, + Bool (*callback)( +#if NeedNestedPrototypes + Xim, INT16, XPointer, XPointer +#endif + ), + XPointer call_data +#endif +); + +extern void _XimFlush( +#if NeedFunctionPrototypes + Xim im +#endif +); + +extern Bool _XimFilterWaitEvent( +#if NeedFunctionPrototypes + Xim im +#endif +); + +extern void _XimProcError( +#if NeedFunctionPrototypes + Xim im, + Xic ic, + XPointer data +#endif +); + +#ifdef EXT_MOVE +extern CARD32 _XimExtenArgCheck( +#if NeedFunctionProtoTypes + XIMArg *arg +#endif +); +#endif + +extern Bool _XimCbDispatch( +#if NeedFunctionPrototypes + Xim im, + INT16 len, + XPointer data, + XPointer call_data +#endif +); + +extern void _XimGetResourceName( +#if NeedFunctionPrototypes + Xim im, + char *res_name, + char *res_class +#endif +); + +extern Bool _XimLocalFilter( +#if NeedFunctionPrototypes + Display *d, + Window w, + XEvent *ev, + XPointer client_data +#endif +); + +extern XIMResourceList _XimGetResourceListRecByQuark( +#if NeedFunctionPrototypes + XIMResourceList res_list, + unsigned int list_num, + XrmQuark quark +#endif +); + +extern Bool _XimReconnectModeCreateIC( +#if NeedFunctionPrototypes + Xic ic +#endif +); + +extern char *_XimLocalSetICValues( +#if NeedFunctionPrototypes + XIC ic, + XIMArg *values +#endif +); + +extern char * _XimLocalGetICValues( +#if NeedFunctionPrototypes + XIC ic, + XIMArg *values +#endif +); + +extern int _XimLocalMbLookupString( +#if NeedFunctionPrototypes + XIC ic, + XKeyEvent *ev, + char *buffer, + int bytes, + KeySym *keysym, + Status *status +#endif +); + +extern int _XimLocalWcLookupString( +#if NeedFunctionPrototypes + XIC ic, + XKeyEvent *ev, + wchar_t *buffer, + int bytes, + KeySym *keysym, + Status *status +#endif +); + +extern Bool _XimThaiFilter( +#if NeedFunctionPrototypes + Display *d, + Window w, + XEvent *ev, + XPointer client_data +#endif +); + +extern XIC _XimThaiCreateIC( +#if NeedFunctionPrototypes + XIM im, + XIMArg *values +#endif +); + +extern Status _XimThaiCloseIM( +#if NeedFunctionPrototypes + XIM xim +#endif +); + +#ifdef XIM_CONNECTABLE +extern void _XimSetProtoResource( +#if NeedFunctionPrototypes + Xim im +#endif +); + +extern Bool _XimConnectServer( +#if NeedFunctionPrototypes + Xim im +#endif +); + +extern Bool _XimDelayModeSetAttr( +#if NeedFunctionPrototypes + Xim im +#endif +); + +extern void _XimServerReconectableDestroy( +#if NeedFunctionPrototypes + void +#endif +); + +extern Bool _XimReCreateIC( +#if NeedFunctionPrototypes + Xic ic +#endif +); + +extern Bool _XimEncodeSavedIMATTRIBUTE( +#if NeedFunctionPrototypes + Xim im, + XIMResourceList res_list, + unsigned int res_num, + int *idx, + char *buf, + int size, + int *ret_len, + XPointer top, + unsigned long mode +#endif +); + +extern Bool _XimEncodeSavedICATTRIBUTE( +#if NeedFunctionPrototypes + Xic ic, + XIMResourceList res_list, + unsigned int res_num, + int *idx, + char *buf, + int size, + int *ret_len, + XPointer top, + unsigned long mode +#endif +); +#endif + +#endif /* _XIMINT_H */ diff --git a/src/xlibi18n/XimintL.h b/src/xlibi18n/XimintL.h new file mode 100644 index 00000000..720a78bd --- /dev/null +++ b/src/xlibi18n/XimintL.h @@ -0,0 +1,78 @@ +/* $Xorg: XimintL.h,v 1.3 2000/08/17 19:45:05 cpqbld Exp $ */ +/****************************************************************** + + Copyright 1991, 1992, 1993, 1994 by FUJITSU LIMITED + Copyright 1993 by Digital Equipment Corporation + +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 FUJITSU LIMITED and +Digital Equipment Corporation not be used in advertising or publicity +pertaining to distribution of the software without specific, written +prior permission. FUJITSU LIMITED and Digital Equipment Corporation +makes no representations about the suitability of this software for +any purpose. It is provided "as is" without express or implied +warranty. + +FUJITSU LIMITED AND DIGITAL EQUIPMENT CORPORATION DISCLAIM ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +FUJITSU LIMITED AND DIGITAL EQUIPMENT CORPORATION 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. + + Author: Takashi Fujiwara FUJITSU LIMITED + fujiwara@a80.tech.yk.fujitsu.co.jp + Modifier: Franky Ling Digital Equipment Corporation + frankyling@hgrd01.enet.dec.com + +******************************************************************/ + +#ifndef _XIMINTL_H +#define _XIMINTL_H + +#define COMPOSE_FILE "Compose" + +/* + * Data Structure for Local Processing + */ +typedef struct _DefTree { + struct _DefTree *next; /* another Key definition */ + struct _DefTree *succession; /* successive Key Sequence */ + /* Key definitions */ + unsigned modifier_mask; + unsigned modifier; + KeySym keysym; /* leaf only */ + char *mb; + wchar_t *wc; /* make from mb */ + KeySym ks; +} DefTree; + +typedef struct _XimLocalPrivateRec { + XIC current_ic; + DefTree *top; + XlcConv ctom_conv; + XlcConv ctow_conv; +} XimLocalPrivateRec; + +typedef struct _XicThaiPart { + int comp_state; + KeySym keysym; + int input_mode; +} XicThaiPart; + +typedef struct _XicLocalPrivateRec { + long value_mask; + DefTree *context; + DefTree *composed; + XicThaiPart thai; + + XIMResourceList ic_resources; + unsigned int ic_num_resources; +} XicLocalPrivateRec; +#endif /* _XIMINTL_H */ diff --git a/src/xlibi18n/XimintP.h b/src/xlibi18n/XimintP.h new file mode 100644 index 00000000..28e09e04 --- /dev/null +++ b/src/xlibi18n/XimintP.h @@ -0,0 +1,301 @@ +/* $Xorg: XimintP.h,v 1.3 2000/08/17 19:45:05 cpqbld Exp $ */ +/****************************************************************** + + Copyright 1991, 1992 by Sun Microsystems, Inc. + Copyright 1992, 1993, 1994 by FUJITSU LIMITED + Copyright 1993, 1994 by Sony Corporation + +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 Sun Microsystems, Inc., FUJITSU +LIMITED and Sony Corporation not be used in advertising or publicity +pertaining to distribution of the software without specific, written +prior permission. Sun Microsystems, Inc., FUJITSU LIMITED and Sony +Corporation makes no representations about the suitability of this +software for any purpose. It is provided "as is" without express or +implied warranty. + +Sun Microsystems Inc. ,FUJITSU LIMITED AND SONY CORPORATION DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL Sun Microsystems, Inc., +FUJITSU LIMITED, SONY CORPORATIN 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. + + Author: Hideki Hiura (hhiura@Sun.COM) Sun Microsystems, Inc. + Takashi Fujiwara FUJITSU LIMITED + fujiwara@a80.tech.yk.fujitsu.co.jp + Makoto Wakamatsu Sony Corporation + makoto@sm.sony.co.jp + Hiroyuki Miyamoto Digital Equipment Corporation + miyamoto@jrd.dec.com + +******************************************************************/ + +#ifndef _XIMINTP_H +#define _XIMINTP_H + +#include "XimProto.h" +#include "XlcPublic.h" + +/* + * for protocol layer callback function + */ +typedef Bool (*XimProtoIntrProc)( +#if NeedFunctionPrototypes + Xim, INT16, XPointer, XPointer +#endif +); +typedef struct _XimProtoIntrRec { + XimProtoIntrProc func; + CARD16 major_code; + CARD16 minor_code; + XPointer call_data; + struct _XimProtoIntrRec *next; +} XimProtoIntrRec; + +/* + * for transport layer methods + */ +typedef Bool (*XimTransConnectProc)( +#if NeedFunctionPrototypes + Xim +#endif +); +typedef Bool (*XimTransShutdownProc)( +#if NeedFunctionPrototypes + Xim +#endif +); +typedef Bool (*XimTransWriteProc)( +#if NeedFunctionPrototypes + Xim, INT16, XPointer +#endif +); +typedef Bool (*XimTransReadProc)( +#if NeedFunctionPrototypes + Xim, XPointer, int, int * +#endif +); +typedef void (*XimTransFlushProc)( +#if NeedFunctionPrototypes + Xim +#endif +); +typedef Bool (*XimTransRegDispatcher)( +#if NeedNestedPrototypes + Xim, Bool (*)(Xim, INT16, XPointer, XPointer), XPointer +#endif +); +typedef Bool (*XimTransCallDispatcher)( +#if NeedFunctionPrototypes + Xim, INT16, XPointer +#endif +); + +/* + * private part of IM + */ +typedef struct _XimProtoPrivateRec { + Window im_window; + XIMID imid; + CARD16 unused; + XIMStyles *default_styles; + CARD32 *im_onkeylist; + CARD32 *im_offkeylist; + BITMASK32 flag; + + BITMASK32 registed_filter_event; + EVENTMASK forward_event_mask; + EVENTMASK synchronous_event_mask; + + XimProtoIntrRec *intrproto; + XIMResourceList im_inner_resources; + unsigned int im_num_inner_resources; + XIMResourceList ic_inner_resources; + unsigned int ic_num_inner_resources; + char *hold_data; + int hold_data_len; + char *locale_name; + CARD16 protocol_major_version; + CARD16 protocol_minor_version; + XrmQuark *saved_imvalues; + int num_saved_imvalues; + + XlcConv ctom_conv; + XlcConv ctow_conv; + + /* + * transport specific + */ + XimTransConnectProc connect; + XimTransShutdownProc shutdown; + XimTransWriteProc write; + XimTransReadProc read; + XimTransFlushProc flush; + XimTransRegDispatcher register_dispatcher; + XimTransCallDispatcher call_dispatcher; + XPointer spec; +} XimProtoPrivateRec; + +/* + * bit mask for the flag of XIMPrivateRec + */ +#define SERVER_CONNECTED (1L) +#define DYNAMIC_EVENT_FLOW (1L << 1) +#define USE_AUTHORIZATION_FUNC (1L << 2) +#ifdef XIM_CONNECTABLE +#define DELAYBINDABLE (1L << 3) +#define RECONNECTABLE (1L << 4) +#endif /* XIM_CONNECTABLE */ + +/* + * macro for the flag of XIMPrivateRec + */ +#define IS_SERVER_CONNECTED(im) \ + ((((Xim)im))->private.proto.flag & SERVER_CONNECTED) +#define MARK_SERVER_CONNECTED(im) \ + ((((Xim)im))->private.proto.flag |= SERVER_CONNECTED) +#define UNMARK_SERVER_CONNECTED(im) \ + ((((Xim)im))->private.proto.flag &= ~SERVER_CONNECTED) + +#define IS_DYNAMIC_EVENT_FLOW(im) \ + (((Xim)im)->private.proto.flag & DYNAMIC_EVENT_FLOW) +#define MARK_DYNAMIC_EVENT_FLOW(im) \ + (((Xim)im)->private.proto.flag |= DYNAMIC_EVENT_FLOW) + +#define IS_USE_AUTHORIZATION_FUNC(im) \ + (((Xim)im)->private.proto.flag & USE_AUTHORIZATION_FUNC) +#define MARK_USE_AUTHORIZATION_FUNC(im) \ + (((Xim)im)->private.proto.flag |= USE_AUTHORIZATION_FUNC) + +#ifdef XIM_CONNECTABLE +#define IS_DELAYBINDABLE(im) \ + (((Xim)im)->private.proto.flag & DELAYBINDABLE) +#define MARK_DELAYBINDABLE(im) \ + (((Xim)im)->private.proto.flag |= DELAYBINDABLE) + +#define IS_RECONNECTABLE(im) \ + (((Xim)im)->private.proto.flag & RECONNECTABLE) +#define MARK_RECONNECTABLE(im) \ + (((Xim)im)->private.proto.flag |= RECONNECTABLE) + +#define IS_CONNECTABLE(im) \ + (((Xim)im)->private.proto.flag & (DELAYBINDABLE|RECONNECTABLE)) +#define UNMAKE_CONNECTABLE(im) \ + (((Xim)im)->private.proto.flag &= ~(DELAYBINDABLE|RECONNECTABLE)) +#endif /* XIM_CONNECTABLE */ + +/* + * bit mask for the register_filter_event of XIMPrivateRec/XICPrivateRec + */ +#define KEYPRESS_MASK (1L) +#define KEYRELEASE_MASK (1L << 1) +#define DESTROYNOTIFY_MASK (1L << 2) + +typedef struct _XimCommitInfoRec { + struct _XimCommitInfoRec *next; + char *string; + int string_len; + KeySym *keysym; + int keysym_len; +} XimCommitInfoRec, *XimCommitInfo; + +typedef struct _XimPendingCallback { + int major_opcode; + Xim im; + Xic ic; + char *proto; + int proto_len; + struct _XimPendingCallback *next; +} XimPendingCallbackRec, *XimPendingCallback; + + +/* + * private part of IC + */ +typedef struct _XicProtoPrivateRec { + XICID icid; /* ICID */ + CARD16 dmy; + BITMASK32 flag; /* Input Mode */ + + BITMASK32 registed_filter_event; /* registed filter mask */ + EVENTMASK forward_event_mask; /* forward event mask */ + EVENTMASK synchronous_event_mask;/* sync event mask */ + EVENTMASK filter_event_mask; /* negrect event mask */ + EVENTMASK intercept_event_mask; /* deselect event mask */ + EVENTMASK select_event_mask; /* select event mask */ + + char *preedit_font; /* Base font name list */ + int preedit_font_length; /* length of base font name */ + char *status_font; /* Base font name list */ + int status_font_length; /* length of base font name */ + + XimCommitInfo commit_info; + XIMResourceList ic_resources; + unsigned int ic_num_resources; + XIMResourceList ic_inner_resources; + unsigned int ic_num_inner_resources; + XrmQuark *saved_icvalues; + int num_saved_icvalues; + XimPendingCallback pend_cb_que; + Bool waitCallback; +} XicProtoPrivateRec ; + +/* + * bit mask for the flag of XICPrivateRec + */ +#define IC_CONNECTED (1L) +#define FABLICATED (1L << 1) +#define NEED_SYNC_REPLY (1L << 2) + +/* + * macro for the flag of XICPrivateRec + */ +#define IS_IC_CONNECTED(ic) \ + (((Xic)ic)->private.proto.flag & IC_CONNECTED) +#define MARK_IC_CONNECTED(ic) \ + (((Xic)ic)->private.proto.flag |= IC_CONNECTED) +#define UNMARK_IC_CONNECTED(ic) \ + (((Xic)ic)->private.proto.flag &= ~IC_CONNECTED) + +#define IS_FABLICATED(ic) \ + (((Xic)ic)->private.proto.flag & FABLICATED) +#define MARK_FABLICATED(ic) \ + (((Xic)ic)->private.proto.flag |= FABLICATED) +#define UNMARK_FABLICATED(ic) \ + (((Xic)ic)->private.proto.flag &= ~FABLICATED) + +#define IS_NEED_SYNC_REPLY(ic) \ + (((Xic)ic)->private.proto.flag & NEED_SYNC_REPLY) +#define MARK_NEED_SYNC_REPLY(ic) \ + (((Xic)ic)->private.proto.flag |= NEED_SYNC_REPLY) +#define UNMARK_NEED_SYNC_REPLY(ic) \ + (((Xic)ic)->private.proto.flag &= ~NEED_SYNC_REPLY) + +/* + * macro for the filter_event_mask of XICPrivateRec + */ +#define IS_NEGLECT_EVENT(ic, mask) \ + (((Xic)ic)->private.proto.filter_event_mask & (mask)) + +/* + * macro for the forward_event_mask of XICPrivateRec + */ +#define IS_FORWARD_EVENT(ic, mask) \ + (((Xic)ic)->private.proto.forward_event_mask & (mask)) + +/* + * macro for the synchronous_event_mask of XICPrivateRec + */ +#define IS_SYNCHRONOUS_EVENT(ic, mask) \ + ((((Xic)ic)->private.proto.synchronous_event_mask & (mask)) ? True: False) + +#define XIM_MAXIMNAMELEN 64 +#define XIM_MAXLCNAMELEN 64 + +#endif /* _XIMINTP_H */ diff --git a/src/xlibi18n/XlcDL.c b/src/xlibi18n/XlcDL.c new file mode 100644 index 00000000..210bd731 --- /dev/null +++ b/src/xlibi18n/XlcDL.c @@ -0,0 +1,650 @@ +/* +Copyright 1985, 1986, 1987, 1991, 1998 The Open Group + +Portions Copyright 2000 Sun Microsystems, Inc. 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 THE OPEN GROUP OR SUN MICROSYSTEMS, INC. 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 EVEN IF +ADVISED IN ADVANCE OF THE POSSIBILITY OF SUCH DAMAGES. + + +Except as contained in this notice, the names of The Open Group and/or +Sun Microsystems, Inc. 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 and/or Sun Microsystems, +Inc., as applicable. + + +X Window System is a trademark of The Open Group + +OSF/1, OSF/Motif and Motif are registered trademarks, and OSF, the OSF +logo, LBX, X Window System, and Xinerama are trademarks of the Open +Group. All other trademarks and registered trademarks mentioned herein +are the property of their respective owners. No right, title or +interest in or to any trademark, service mark, logo or trade name of +Sun Microsystems, Inc. or its licensors is granted. + +*/ + +#include <stdio.h> +#if defined(hpux) +#include <dl.h> +#else +#include <dlfcn.h> +#endif +#include <ctype.h> + +#include "Xlibint.h" +#include "XlcPublic.h" +#include "XlcPubI.h" + +#ifdef _LP64 +#if defined(__sparcv9) +#define _MACH64_NAME "sparcv9" +#define _MACH64_NAME_LEN (sizeof (_MACH64_NAME) - 1) +#else /* !defined(__sparcv9) */ +#error "Unknown architecture" +#endif /* defined(__sparcv9) */ +#endif /* _LP64 */ + +#define XI18N_DLREL 2 + +#define iscomment(ch) ((ch) == '\0' || (ch) == '#') + +typedef enum { + XLC_OBJECT, + XIM_OBJECT, + XOM_OBJECT +} XI18NDLType; + +typedef struct { + XI18NDLType type; + int locale_name_len; + char *locale_name; + char *dl_name; + char *open; + char *im_register; + char *im_unregister; + int dl_release; +#if defined(hpux) + shl_t dl_module; +#else + void *dl_module; +#endif +} XI18NObjectsListRec, *XI18NObjectsList; + +#define OBJECT_INIT_LEN 8 +#define OBJECT_INC_LEN 4 +static int lc_len = 0; +static XI18NObjectsListRec *xi18n_objects_list = NULL; +static int lc_count = 0; + +static int +parse_line(line, argv, argsize) +char *line; +char **argv; +int argsize; +{ + int argc = 0; + char *p = line; + + while (argc < argsize) { + while (isspace(*p)) { + ++p; + } + if (iscomment(*p)){ + break; + } + argv[argc++] = p; + while (!isspace(*p)) { + ++p; + } + if (iscomment(*p)) { + break; + } + *p++ = '\0'; + } + return argc; +} + +static void +resolve_object(path, lc_name) +char *path; +char *lc_name; +{ + char filename[BUFSIZ]; + FILE *fp; + char buf[BUFSIZ]; + + if (lc_len == 0) { /* True only for the 1st time */ + lc_len = OBJECT_INIT_LEN; + xi18n_objects_list = (XI18NObjectsList) + Xmalloc(sizeof(XI18NObjectsListRec) * lc_len); + if (!xi18n_objects_list) return; + } +/* +1266793 +Limit the length of path to prevent stack buffer corruption. + sprintf(filename, "%s/%s", path, "XI18N_OBJS"); +*/ + sprintf(filename, "%.*s/%s", BUFSIZ - 12, path, "XI18N_OBJS"); + fp = fopen(filename, "r"); + if (fp == (FILE *)NULL){ + return; + } + + while (fgets(buf, BUFSIZ, fp) != NULL){ + char *p = buf; + int n; + char *args[6]; + while (isspace(*p)){ + ++p; + } + if (iscomment(*p)){ + continue; + } + + if (lc_count == lc_len) { + lc_len += OBJECT_INC_LEN; + xi18n_objects_list = (XI18NObjectsList) + Xrealloc(xi18n_objects_list, + sizeof(XI18NObjectsListRec) * lc_len); + if (!xi18n_objects_list) return; + } + n = parse_line(p, args, 6); + + if (n == 3 || n == 5) { + if (!strcmp(args[0], "XLC")){ + xi18n_objects_list[lc_count].type = XLC_OBJECT; + } else if (!strcmp(args[0], "XOM")){ + xi18n_objects_list[lc_count].type = XOM_OBJECT; + } else if (!strcmp(args[0], "XIM")){ + xi18n_objects_list[lc_count].type = XIM_OBJECT; + } + xi18n_objects_list[lc_count].dl_name = strdup(args[1]); + xi18n_objects_list[lc_count].open = strdup(args[2]); + xi18n_objects_list[lc_count].dl_release = XI18N_DLREL; + xi18n_objects_list[lc_count].locale_name = strdup(lc_name); + xi18n_objects_list[lc_count].dl_module = (void*)NULL; + if (n == 5) { + xi18n_objects_list[lc_count].im_register = strdup(args[3]); + xi18n_objects_list[lc_count].im_unregister = strdup(args[4]); + } else { + xi18n_objects_list[lc_count].im_register = NULL; + xi18n_objects_list[lc_count].im_unregister = NULL; + } + lc_count++; + } + } + fclose(fp); +} + +static char* +__lc_path(dl_name, lc_dir) +const char *dl_name; +const char *lc_dir; +{ + char *path; + size_t len; + +#ifdef _LP64 + len = (lc_dir ? strlen(lc_dir) : 0 ) + + (dl_name ? strlen(dl_name) : 0) + _MACH64_NAME_LEN + 10; + path = Xmalloc(len + 1); + + if (strchr(dl_name, '/') != NULL) { + char *tmp = strdup(dl_name); + char *dl_dir, *dl_file; + char *slash_p; + slash_p = strchr(tmp, '/'); + *slash_p = '\0'; + dl_dir = tmp; + dl_file = ++slash_p; + + slash_p = strrchr(lc_dir, '/'); + *slash_p = '\0'; + strcpy(path, lc_dir); strcat(path, "/"); + strcat(path, dl_dir); strcat(path, "/"); + strcat(path, _MACH64_NAME); strcat(path, "/"); + strcat(path, dl_file); strcat(path, ".so.2"); + + *slash_p = '/'; + Xfree(tmp); + } else { + strcpy(path, lc_dir); strcat(path, "/"); + strcat(path, _MACH64_NAME); strcat(path, "/"); + strcat(path, dl_name); strcat(path, ".so.2"); + } +#else + len = (lc_dir ? strlen(lc_dir) : 0 ) + + (dl_name ? strlen(dl_name) : 0) + 10; + path = Xmalloc(len + 1); + + if (strchr(dl_name, '/') != NULL) { + char *slash_p; + slash_p = strrchr(lc_dir, '/'); + *slash_p = '\0'; + strcpy(path, lc_dir); strcat(path, "/"); + strcat(path, dl_name); strcat(path, ".so.2"); + *slash_p = '/'; + } else { + strcpy(path, lc_dir); strcat(path, "/"); + strcat(path, dl_name); strcat(path, ".so.2"); + } +#endif + return path; +} + +XLCd +_XlcDynamicLoad(lc_name) + char *lc_name; +{ + XLCd lcd = (XLCd)NULL; + XLCd (*lc_loader)() = (XLCd(*)())NULL; + char *path; + int count; + XI18NObjectsList objects_list; + char lc_dir[BUFSIZE]; +#if defined(hpux) + int getsyms_cnt, i; + struct shl_symbol *symbols; +#endif + + if (lc_name == NULL) return (XLCd)NULL; + + if (_XlcLocaleDirName(lc_dir, lc_name) == (char*)NULL) return (XLCd)NULL; + + resolve_object(lc_dir, lc_name); + + objects_list = xi18n_objects_list; + count = lc_count; + for (; count-- > 0; objects_list++) { + if (objects_list->type != XLC_OBJECT || + strcmp(objects_list->locale_name, lc_name)) continue; + if (!objects_list->dl_module) { + path = __lc_path(objects_list->dl_name, lc_dir); +#if defined(hpux) + objects_list->dl_module = shl_load(path, BIND_DEFERRED, 0L); +#else + objects_list->dl_module = dlopen(path, RTLD_LAZY); +#endif + Xfree(path); + if (!objects_list->dl_module) continue; + } +#if defined(hpux) + getsyms_cnt = shl_getsymbols(objects_list->dl_module, TYPE_PROCEDURE, + EXPORT_SYMBOLS, malloc, &symbols); + + for(i=0; i<getsyms_cnt; i++) { + if(!strcmp(symbols[i].name, objects_list->open)) { + lc_loader = symbols[i].value; + break; + } + } + + if(getsyms_cnt > 0) { + free(symbols); + } +#else + lc_loader = (XLCd(*)())dlsym(objects_list->dl_module, + objects_list->open); +#endif + if (!lc_loader) continue; + lcd = (*lc_loader)(lc_name); + if (lcd != (XLCd)NULL) { + break; + } +#if defined(hpux) + shl_unload(objects_list->dl_module); +#else + dlclose(objects_list->dl_module); +#endif + objects_list->dl_module = NULL; + } + return (XLCd)lcd; +} + +static XIM +#if NeedFunctionPrototypes +_XDynamicOpenIM(XLCd lcd, Display *display, XrmDatabase rdb, + char *res_name, char *res_class) +#else +_XDynamicOpenIM(lcd, display, rdb, res_name, res_class) +XLCd lcd; +Display *display; +XrmDatabase rdb; +char *res_name, *res_class; +#endif +{ + XIM im = (XIM)NULL; + char *path; + char lc_dir[BUFSIZE]; + char *lc_name; + XIM (*im_openIM)() = (XIM(*)())NULL; + int count; + XI18NObjectsList objects_list = xi18n_objects_list; +#if defined(hpux) + int getsyms_cnt, i; + struct shl_symbol *symbols; +#endif + + lc_name = lcd->core->name; + + if (_XlcLocaleDirName(lc_dir, lc_name) == NULL) return (XIM)0; + + count = lc_count; + for (; count-- > 0; objects_list++) { + if (objects_list->type != XIM_OBJECT || + strcmp(objects_list->locale_name, lc_name)) continue; + if (!objects_list->dl_module) { + path = __lc_path(objects_list->dl_name, lc_dir); +#if defined(hpux) + objects_list->dl_module = shl_load(path, BIND_DEFERRED, 0L); +#else + objects_list->dl_module = dlopen(path, RTLD_LAZY); +#endif + Xfree(path); + if (!objects_list->dl_module) continue; + } +#if defined(hpux) + getsyms_cnt = shl_getsymbols(objects_list->dl_module, TYPE_PROCEDURE, + EXPORT_SYMBOLS, malloc, &symbols); + + for(i=0; i<getsyms_cnt; i++) { + if(!strcmp(symbols[i].name, objects_list->open)) { + im_openIM = symbols[i].value; + break; + } + } + + if(getsyms_cnt > 0) { + free(symbols); + } +#else + im_openIM = (XIM(*)())dlsym(objects_list->dl_module, + objects_list->open); + if (!im_openIM) continue; +#endif + im = (*im_openIM)(lcd, display, rdb, res_name, res_class); + if (im != (XIM)NULL) { + break; + } + im_openIM = 0; +#if defined(hpux) + shl_unload(objects_list->dl_module); +#else + dlclose(objects_list->dl_module); +#endif + objects_list->dl_module = NULL; + } + return (XIM)im; +} + +static Bool +_XDynamicRegisterIMInstantiateCallback(lcd, display, rdb, + res_name, res_class, + callback, client_data) +XLCd lcd; +Display *display; +XrmDatabase rdb; +char *res_name, *res_class; +XIMProc callback; +XPointer *client_data; +{ + char *path; + char lc_dir[BUFSIZE]; + char *lc_name; + Bool (*im_registerIM)() = (Bool(*)())NULL; + Bool ret_flag = False; + int count; + XI18NObjectsList objects_list = xi18n_objects_list; +#if defined(hpux) + int getsyms_cnt, i; + struct shl_symbol *symbols; +#endif + + lc_name = lcd->core->name; + + if (_XlcLocaleDirName(lc_dir, lc_name) == NULL) return False; + + count = lc_count; + for (; count-- > 0; objects_list++) { + if (objects_list->type != XIM_OBJECT || + strcmp(objects_list->locale_name, lc_name)) continue; + if (!objects_list->dl_module) { + path = __lc_path(objects_list->dl_name, lc_dir); +#if defined(hpux) + objects_list->dl_module = shl_load(path, BIND_DEFERRED, 0L); +#else + objects_list->dl_module = dlopen(path, RTLD_LAZY); +#endif + Xfree(path); + if (!objects_list->dl_module) continue; + } +#if defined(hpux) + getsyms_cnt = shl_getsymbols(objects_list->dl_module, TYPE_PROCEDURE, + EXPORT_SYMBOLS, malloc, &symbols); + + for(i=0; i<getsyms_cnt; i++) { + if(!strcmp(symbols[i].name, objects_list->open)) { + im_registerIM = symbols[i].value; + break; + } + } + + if(getsyms_cnt > 0) { + free(symbols); + } +#else + im_registerIM = (Bool(*)())dlsym(objects_list->dl_module, + objects_list->im_register); + if (!im_registerIM) continue; +#endif + ret_flag = (*im_registerIM)(lcd, display, rdb, + res_name, res_class, + callback, client_data); + if (ret_flag) break; + + im_registerIM = 0; +#if defined(hpux) + shl_unload(objects_list->dl_module); +#else + dlclose(objects_list->dl_module); +#endif + objects_list->dl_module = NULL; + } + return (Bool)ret_flag; +} + +static Bool +_XDynamicUnRegisterIMInstantiateCallback(lcd, display, rdb, + res_name, res_class, + callback, client_data) +XLCd lcd; +Display *display; +XrmDatabase rdb; +char *res_name, *res_class; +XIMProc callback; +XPointer *client_data; +{ + char *path; + char lc_dir[BUFSIZE]; + char *lc_name; + Bool (*im_unregisterIM)() = (Bool(*)())NULL; + Bool ret_flag = False; + int count; + XI18NObjectsList objects_list = xi18n_objects_list; +#if defined(hpux) + int getsyms_cnt, i; + struct shl_symbol *symbols; +#endif + + lc_name = lcd->core->name; + if (_XlcLocaleDirName(lc_dir, lc_name) == NULL) return False; + + count = lc_count; + for (; count-- > 0; objects_list++) { + if (objects_list->type != XIM_OBJECT || + strcmp(objects_list->locale_name, lc_name)) continue; + if (!objects_list->dl_module) { + path = __lc_path(objects_list->dl_name, lc_dir); +#if defined(hpux) + objects_list->dl_module = shl_load(path, BIND_DEFERRED, 0L); +#else + objects_list->dl_module = dlopen(path, RTLD_LAZY); +#endif + Xfree(path); + if (!objects_list->dl_module) continue; + } +#if defined(hpux) + getsyms_cnt = shl_getsymbols(objects_list->dl_module, TYPE_PROCEDURE, + EXPORT_SYMBOLS, malloc, &symbols); + + for(i=0; i<getsyms_cnt; i++) { + if(!strcmp(symbols[i].name, objects_list->open)) { + im_unregisterIM = symbols[i].value; + break; + } + } + + if(getsyms_cnt > 0) { + free(symbols); + } +#else + im_unregisterIM = (Bool(*)())dlsym(objects_list->dl_module, + objects_list->im_unregister); + + if (!im_unregisterIM) continue; +#endif + ret_flag = (*im_unregisterIM)(lcd, display, rdb, + res_name, res_class, + callback, client_data); + if (ret_flag) break; + + im_unregisterIM = 0; +#if defined(hpux) + shl_unload(objects_list->dl_module); +#else + dlclose(objects_list->dl_module); +#endif + objects_list->dl_module = NULL; + } + return (Bool)ret_flag; +} + +Bool +_XInitDynamicIM(lcd) +XLCd lcd; +{ + if(lcd == (XLCd)NULL) + return False; + lcd->methods->open_im = _XDynamicOpenIM; + lcd->methods->register_callback = _XDynamicRegisterIMInstantiateCallback; + lcd->methods->unregister_callback = _XDynamicUnRegisterIMInstantiateCallback; + return True; +} + +static XOM +#if NeedFunctionPrototypes +_XDynamicOpenOM(XLCd lcd, Display *display, XrmDatabase rdb, + _Xconst char *res_name, _Xconst char *res_class) +#else +_XDynamicOpenOM(lcd, display, rdb, res_name, res_class) +XLCd lcd; +Display *display; +XrmDatabase rdb; +char *res_name; +char *res_class; +#endif +{ + XOM om = (XOM)NULL; + int count; + char *path; + char lc_dir[BUFSIZE]; + char *lc_name; + XOM (*om_openOM)() = (XOM(*)())NULL; + XI18NObjectsList objects_list = xi18n_objects_list; +#if defined(hpux) + int getsyms_cnt, i; + struct shl_symbol *symbols; +#endif + + lc_name = lcd->core->name; + + if (_XlcLocaleDirName(lc_dir, lc_name) == NULL) return (XOM)0; + + count = lc_count; + for (; count-- > 0; objects_list++) { + if (objects_list->type != XOM_OBJECT || + strcmp(objects_list->locale_name, lc_name)) continue; + if (!objects_list->dl_module) { + path = __lc_path(objects_list->dl_name, lc_dir); +#if defined(hpux) + objects_list->dl_module = shl_load(path, BIND_DEFERRED, 0L); +#else + objects_list->dl_module = dlopen(path, RTLD_LAZY); +#endif + Xfree(path); + if (!objects_list->dl_module) continue; + } +#if defined(hpux) + getsyms_cnt = shl_getsymbols(objects_list->dl_module, TYPE_PROCEDURE, + EXPORT_SYMBOLS, malloc, &symbols); + + for(i=0; i<getsyms_cnt; i++) { + if(!strcmp(symbols[i].name, objects_list->open)) { + om_openOM = symbols[i].value; + break; + } + } + + if(getsyms_cnt > 0) { + free(symbols); + } +#else + om_openOM = (XOM(*)())dlsym(objects_list->dl_module, + objects_list->open); + if (!om_openOM) continue; +#endif + om = (*om_openOM)(lcd, display, rdb, res_name, res_class); + if (om != (XOM)NULL) { + break; + } + om_openOM = 0; +#if defined(hpux) + shl_unload(objects_list->dl_module); +#else + dlclose(objects_list->dl_module); +#endif + objects_list->dl_module = NULL; + } + return (XOM)om; +} + +Bool +_XInitDynamicOM(lcd) + XLCd lcd; +{ + if(lcd == (XLCd)NULL) + return False; + + lcd->methods->open_om = _XDynamicOpenOM; + + return True; +} diff --git a/src/xlibi18n/XlcGeneric.h b/src/xlibi18n/XlcGeneric.h new file mode 100644 index 00000000..96f49fe8 --- /dev/null +++ b/src/xlibi18n/XlcGeneric.h @@ -0,0 +1,146 @@ +/* $Xorg: XlcGeneric.h,v 1.3 2000/08/17 19:45:06 cpqbld Exp $ */ +/* + * Copyright 1992, 1993 by TOSHIBA Corp. + * + * 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 TOSHIBA not be used in advertising + * or publicity pertaining to distribution of the software without specific, + * written prior permission. TOSHIBA make no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * TOSHIBA DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING + * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL + * TOSHIBA 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. + * + * Author: Katsuhisa Yano TOSHIBA Corp. + * mopi@osa.ilab.toshiba.co.jp + */ +/* + * Copyright 1995 by FUJITSU LIMITED + * This is source code modified by FUJITSU LIMITED under the Joint + * Development Agreement for the CDE/Motif PST. + * + * Modifier: Takanori Tateno FUJITSU LIMITED + * + */ + +#ifndef _XLCGENERIC_H_ +#define _XLCGENERIC_H_ + +#include "XlcPubI.h" + +typedef struct _ByteInfo { + unsigned char start,end; +} ByteInfoRec, *ByteInfo; + +typedef struct _ByteInfoList { + int M; /* 1 <= M <= length */ + int byteinfo_num; + ByteInfo byteinfo; +} ByteInfoListRec, *ByteInfoList; + +/* conversion_type values */ +#define LOCALCONV 1 +#define FILECONV 2 +#define FUNCTIONCONV 4 + +typedef struct _Conversion { + unsigned long conversion_type; + int conv_num; + FontScope convlist; + char *cnv_file; + XlcConv cnvfunc; +} ConversionRec, *Conversion; + +typedef struct _ExtdSegment { + char *name; + XlcSide side; + FontScope area; + int area_num; + XlcCharSet charset; +} ExtdSegmentRec, *ExtdSegment; + +typedef struct _SegConvRec { + int length; + char *source_encoding; + XlcCharSet source; + char *destination_encoding; + XlcCharSet dest; + FontScopeRec range; + int conv_num; + FontScope conv; +} SegConvRec, *SegConv; + +typedef struct _ParseInfoRec *ParseInfo; + +typedef struct _CodeSetRec { + XlcCharSet *charset_list; + int num_charsets; + int cs_num; + XlcSide side; + int length; + ByteInfoList byteM; + Conversion mbconv; + Conversion ctconv; + ExtdSegment ctextseg; + ParseInfo parse_info; + unsigned long wc_encoding; +} CodeSetRec, *CodeSet; + +typedef enum { + E_GL, /* GL encoding */ + E_GR, /* GR encoding */ + E_SS, /* single shift */ + E_LSL, /* locking shift left */ + E_LSR, /* locking shift right */ + E_LAST +} EncodingType; + +typedef struct _ParseInfoRec { + EncodingType type; + char *encoding; + CodeSet codeset; +} ParseInfoRec; + +/* + * XLCd private data + */ + +#define XLC_GENERIC(lcd, x) (((XLCdGeneric) lcd->core)->gen.x) +#define XLC_GENERIC_PART(lcd) (&(((XLCdGeneric) lcd->core)->gen)) + +typedef struct _XLCdGenericPart { + int codeset_num; + CodeSet *codeset_list; + unsigned char *mb_parse_table; + int mb_parse_list_num; + ParseInfo *mb_parse_list; + unsigned long wc_encode_mask; + unsigned long wc_shift_bits; + CodeSet initial_state_GL; + CodeSet initial_state_GR; + int segment_conv_num; /* UDC */ + SegConv segment_conv; /* UDC */ +#ifndef X_NOT_STDC_ENV + Bool use_stdc_env; + Bool force_convert_to_mb; +#endif +} XLCdGenericPart; + +typedef struct _XLCdGenericRec { + XLCdCoreRec core; + XLCdPublicPart pub; + XLCdGenericPart gen; +} XLCdGenericRec, *XLCdGeneric; + +extern XLCdMethods _XlcGenericMethods; + +#endif /* _XLCGENERIC_H_ */ diff --git a/src/xlibi18n/XlcPubI.h b/src/xlibi18n/XlcPubI.h new file mode 100644 index 00000000..0234f0f4 --- /dev/null +++ b/src/xlibi18n/XlcPubI.h @@ -0,0 +1,252 @@ +/* $Xorg: XlcPubI.h,v 1.4 2000/12/12 12:44:05 coskrey Exp $ */ +/* + * Copyright 1992, 1993 by TOSHIBA Corp. + * + * 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 TOSHIBA not be used in advertising + * or publicity pertaining to distribution of the software without specific, + * written prior permission. TOSHIBA make no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * TOSHIBA DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING + * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL + * TOSHIBA 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. + * + * Author: Katsuhisa Yano TOSHIBA Corp. + * mopi@osa.ilab.toshiba.co.jp + */ + +#ifndef _XLCPUBLICI_H_ +#define _XLCPUBLICI_H_ + +#include "XlcPublic.h" + +#define XLC_PUBLIC(lcd, x) (((XLCdPublic) lcd->core)->pub.x) +#define XLC_PUBLIC_PART(lcd) (&(((XLCdPublic) lcd->core)->pub)) +#define XLC_PUBLIC_METHODS(lcd) (&(((XLCdPublicMethods) lcd->methods)->pub)) + +/* + * XLCd public methods + */ + +typedef struct _XLCdPublicMethodsRec *XLCdPublicMethods; + +typedef XLCd (*XlcPubCreateProc)( +#if NeedFunctionPrototypes + char* /* name */, + XLCdMethods /* methods */ +#endif +); + +typedef Bool (*XlcPubInitializeProc)( +#if NeedFunctionPrototypes + XLCd /* lcd */ +#endif +); + +typedef void (*XlcPubDestroyProc)( +#if NeedFunctionPrototypes + XLCd /* lcd */ +#endif +); + +typedef char* (*XlcPubGetValuesProc)( +#if NeedFunctionPrototypes + XLCd /* lcd */, + XlcArgList /* args */, + int /* num_args */ +#endif +); + +typedef void (*XlcPubGetResourceProc)( +#if NeedFunctionPrototypes + XLCd /* lcd */, + char* /* category */, + char* /* class */, + char*** /* value */, + int* /* count */ +#endif +); + +typedef struct _XLCdPublicMethodsPart { + XLCdPublicMethods superclass; + XlcPubCreateProc create; + XlcPubInitializeProc initialize; + XlcPubDestroyProc destroy; + XlcPubGetValuesProc get_values; + XlcPubGetResourceProc get_resource; +} XLCdPublicMethodsPart; + +typedef struct _XLCdPublicMethodsRec { + XLCdMethodsRec core; + XLCdPublicMethodsPart pub; +} XLCdPublicMethodsRec; + +/* + * XLCd public data + */ + +typedef struct _XLCdPublicPart { + char *siname; /* for _XlcMapOSLocaleName() */ + char *language; /* language part of locale name */ + char *territory; /* territory part of locale name */ + char *codeset; /* codeset part of locale name */ + char *encoding_name; /* encoding name */ + int mb_cur_max; /* ANSI C MB_CUR_MAX */ + Bool is_state_depend; /* state-depend encoding */ + char *default_string; /* for XDefaultString() */ + XPointer xlocale_db; +} XLCdPublicPart; + +typedef struct _XLCdPublicRec { + XLCdCoreRec core; + XLCdPublicPart pub; +} XLCdPublicRec, *XLCdPublic; + +extern XLCdMethods _XlcPublicMethods; + +_XFUNCPROTOBEGIN + +extern XLCd _XlcCreateLC( +#if NeedFunctionPrototypes + char* /* name */, + XLCdMethods /* methods */ +#endif +); + +extern void _XlcDestroyLC( +#if NeedFunctionPrototypes + XLCd /* lcd */ +#endif +); + +extern Bool _XlcParseCharSet( +#if NeedFunctionPrototypes + XlcCharSet /* charset */ +#endif +); + +extern XlcCharSet _XlcCreateDefaultCharSet( +#if NeedFunctionPrototypes + char* /* name */, + char* /* control_sequence */ +#endif +); + +extern XlcCharSet _XlcAddCT( +#if NeedFunctionPrototypes + char* /* name */, + char* /* control_sequence */ +#endif +); + +extern XrmMethods _XrmDefaultInitParseInfo( +#if NeedFunctionPrototypes + XLCd /* lcd */, + XPointer* /* state */ +#endif +); + +extern int _XmbTextPropertyToTextList( +#if NeedFunctionPrototypes + XLCd /* lcd */, + Display* /* dpy */, + XTextProperty* /* text_prop */, + char*** /* list_ret */, + int* /* count_ret */ +#endif +); + +extern int _XwcTextPropertyToTextList( +#if NeedFunctionPrototypes + XLCd /* lcd */, + Display* /* dpy */, + XTextProperty* /* text_prop */, + wchar_t*** /* list_ret */, + int* /* count_ret */ +#endif +); + +extern int _XmbTextListToTextProperty( +#if NeedFunctionPrototypes + XLCd /* lcd */, + Display* /* dpy */, + char** /* list */, + int /* count */, + XICCEncodingStyle /* style */, + XTextProperty* /* text_prop */ +#endif +); + +extern int _XwcTextListToTextProperty( +#if NeedFunctionPrototypes + XLCd /* lcd */, + Display* /* dpy */, + wchar_t** /* list */, + int /* count */, + XICCEncodingStyle /* style */, + XTextProperty* /* text_prop */ +#endif +); + +extern void _XwcFreeStringList( +#if NeedFunctionPrototypes + XLCd /* lcd */, + wchar_t** /* list */ +#endif +); + +extern int _XlcResolveLocaleName( +#if NeedFunctionPrototypes + char* /* lc_name */, + XLCdPublicPart* /* pub */ +#endif +); + +extern int _XlcResolveI18NPath( +#if NeedFunctionPrototypes + char* /* buf */, + int /* buf_len */ +#endif +); + +extern char *_XlcLocaleDirName( +#if NeedFunctionPrototypes + char* /* dir_name */, + char* /* lc_name */ +#endif +); + +extern XPointer _XlcCreateLocaleDataBase( +#if NeedFunctionPrototypes + XLCd /* lcd */ +#endif +); + +extern void _XlcDestroyLocaleDataBase( +#if NeedFunctionPrototypes + XLCd /* lcd */ +#endif +); + +extern void _XlcGetLocaleDataBase( +#if NeedFunctionPrototypes + XLCd /* lcd */, + char* /* category */, + char* /* name */, + char*** /* value */, + int* /* count */ +#endif +); + +_XFUNCPROTOEND + +#endif /* _XLCPUBLICI_H_ */ diff --git a/src/xlibi18n/XlcPublic.h b/src/xlibi18n/XlcPublic.h new file mode 100644 index 00000000..0deb44c1 --- /dev/null +++ b/src/xlibi18n/XlcPublic.h @@ -0,0 +1,287 @@ +/* $Xorg: XlcPublic.h,v 1.3 2000/08/17 19:45:06 cpqbld Exp $ */ +/* + * Copyright 1992, 1993 by TOSHIBA Corp. + * + * 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 TOSHIBA not be used in advertising + * or publicity pertaining to distribution of the software without specific, + * written prior permission. TOSHIBA make no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * TOSHIBA DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING + * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL + * TOSHIBA 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. + * + * Author: Katsuhisa Yano TOSHIBA Corp. + * mopi@osa.ilab.toshiba.co.jp + */ +/* + * Copyright 1995 by FUJITSU LIMITED + * This is source code modified by FUJITSU LIMITED under the Joint + * Development Agreement for the CDE/Motif PST. + * + * Modifier: Takanori Tateno FUJITSU LIMITED + * + */ + +#ifndef _XLCPUBLIC_H_ +#define _XLCPUBLIC_H_ + +#include "Xlcint.h" + +#define XlcNCharSize "charSize" +#define XlcNCodeset "codeset" +#define XlcNControlSequence "controlSequence" +#define XlcNDefaultString "defaultString" +#define XlcNEncodingName "encodingName" +#define XlcNLanguage "language" +#define XlcNMbCurMax "mbCurMax" +#define XlcNName "name" +#define XlcNSetSize "setSize" +#define XlcNSide "side" +#define XlcNStateDependentEncoding "stateDependentEncoding" +#define XlcNTerritory "territory" + +typedef enum { + XlcUnknown, XlcC0, XlcGL, XlcC1, XlcGR, XlcGLGR, XlcOther, XlcNONE +} XlcSide; + +typedef struct _FontScope { + unsigned long start; + unsigned long end; + unsigned long shift; + unsigned long shift_direction; +} FontScopeRec, *FontScope; + +typedef struct _UDCArea { + unsigned long start,end; +} UDCAreaRec, *UDCArea; + +typedef struct _XlcCharSetRec *XlcCharSet; + +typedef char* (*XlcGetCSValuesProc)( +#if NeedFunctionPrototypes + XlcCharSet /* charset */, + XlcArgList /* args */, + int /* num_args */ +#endif +); + +typedef struct _XlcCharSetRec { + char *name; /* character set name */ + XrmQuark xrm_name; + char *encoding_name; /* XLFD encoding name */ + XrmQuark xrm_encoding_name; + XlcSide side; /* GL, GR or others */ + int char_size; /* number of bytes per character */ + int set_size; /* graphic character sets */ + char *ct_sequence; /* control sequence of CT */ + XlcGetCSValuesProc get_values; + /* UDC */ + Bool string_encoding; + UDCArea udc_area; + int udc_area_num; +} XlcCharSetRec; + +/* + * conversion methods + */ + +typedef struct _XlcConvRec *XlcConv; + +typedef XlcConv (*XlcOpenConverterProc)( +#if NeedFunctionPrototypes + XLCd /* from_lcd */, + char* /* from_type */, + XLCd /* to_lcd */, + char* /* to_type */ +#endif +); + +typedef void (*XlcCloseConverterProc)( +#if NeedFunctionPrototypes + XlcConv /* conv */ +#endif +); + +typedef int (*XlcConvertProc)( +#if NeedFunctionPrototypes + XlcConv /* conv */, + XPointer* /* from */, + int* /* from_left */, + XPointer* /* to */, + int* /* to_left */, + XPointer* /* args */, + int /* num_args */ +#endif +); + +typedef void (*XlcResetConverterProc)( +#if NeedFunctionPrototypes + XlcConv /* conv */ +#endif +); + +typedef struct _XlcConvMethodsRec{ + XlcCloseConverterProc close; + XlcConvertProc convert; + XlcResetConverterProc reset; +} XlcConvMethodsRec, *XlcConvMethods; + +/* + * conversion data + */ + +#define XlcNMultiByte "multiByte" +#define XlcNWideChar "wideChar" +#define XlcNCompoundText "compoundText" +#define XlcNString "string" +#define XlcNCharSet "charSet" +#define XlcNCTCharSet "CTcharSet" +#define XlcNChar "char" + +typedef struct _XlcConvRec { + XlcConvMethods methods; + XPointer state; +} XlcConvRec; + + +_XFUNCPROTOBEGIN + +extern Bool _XInitOM( +#if NeedFunctionPrototypes + XLCd /* lcd */ +#endif +); + +extern Bool _XInitIM( +#if NeedFunctionPrototypes + XLCd /* lcd */ +#endif +); + +extern char *_XGetLCValues( +#if NeedVarargsPrototypes + XLCd /* lcd */, + ... +#endif +); + +extern XlcCharSet _XlcGetCharSet( +#if NeedFunctionPrototypes + char* /* name */ +#endif +); + +extern Bool _XlcAddCharSet( +#if NeedFunctionPrototypes + XlcCharSet /* charset */ +#endif +); + +extern char *_XlcGetCSValues( +#if NeedVarargsPrototypes + XlcCharSet /* charset */, + ... +#endif +); + +extern XlcConv _XlcOpenConverter( +#if NeedFunctionPrototypes + XLCd /* from_lcd */, + char* /* from_type */, + XLCd /* to_lcd */, + char* /* to_type */ +#endif +); + +extern void _XlcCloseConverter( +#if NeedFunctionPrototypes + XlcConv /* conv */ +#endif +); + +extern int _XlcConvert( +#if NeedFunctionPrototypes + XlcConv /* conv */, + XPointer* /* from */, + int* /* from_left */, + XPointer* /* to */, + int* /* to_left */, + XPointer* /* args */, + int /* num_args */ +#endif +); + +extern void _XlcResetConverter( +#if NeedFunctionPrototypes + XlcConv /* conv */ +#endif +); + +extern Bool _XlcSetConverter( +#if NeedFunctionPrototypes + XLCd /* from_lcd */, + char* /* from_type */, + XLCd /* to_lcd */, + char* /* to_type */, + XlcOpenConverterProc /* open_converter */ +#endif +); + +extern void _XlcGetResource( +#if NeedFunctionPrototypes + XLCd /* lcd */, + char* /* category */, + char* /* class */, + char*** /* value */, + int* /* count */ +#endif +); + +extern char *_XlcFileName( +#if NeedFunctionPrototypes + XLCd /* lcd */, + char* /* category */ +#endif +); + +extern int _Xwcslen( +#if NeedFunctionPrototypes + wchar_t* /* wstr */ +#endif +); + +extern wchar_t *_Xwcscpy( +#if NeedFunctionPrototypes + wchar_t* /* wstr1 */, + wchar_t* /* wstr2 */ +#endif +); + +extern int _XlcCompareISOLatin1( +#if NeedFunctionPrototypes + char* /* str1 */, + char* /* str2 */ +#endif +); + +extern int _XlcNCompareISOLatin1( +#if NeedFunctionPrototypes + char* /* str1 */, + char* /* str2 */, + int /* len */ +#endif +); + +_XFUNCPROTOEND + +#endif /* _XLCPUBLIC_H_ */ diff --git a/src/xlibi18n/XlcSL.c b/src/xlibi18n/XlcSL.c new file mode 100644 index 00000000..12391b1d --- /dev/null +++ b/src/xlibi18n/XlcSL.c @@ -0,0 +1,79 @@ +/* +Copyright 1985, 1986, 1987, 1991, 1998 The Open Group + +Portions Copyright 2000 Sun Microsystems, Inc. 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 THE OPEN GROUP OR SUN MICROSYSTEMS, INC. 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 EVEN IF +ADVISED IN ADVANCE OF THE POSSIBILITY OF SUCH DAMAGES. + + +Except as contained in this notice, the names of The Open Group and/or +Sun Microsystems, Inc. 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 and/or Sun Microsystems, +Inc., as applicable. + + +X Window System is a trademark of The Open Group + +OSF/1, OSF/Motif and Motif are registered trademarks, and OSF, the OSF +logo, LBX, X Window System, and Xinerama are trademarks of the Open +Group. All other trademarks and registered trademarks mentioned herein +are the property of their respective owners. No right, title or +interest in or to any trademark, service mark, logo or trade name of +Sun Microsystems, Inc. or its licensors is granted. + +*/ + +#include "Xlibint.h" +#include "Xlcint.h" + +extern XIM _XDefaultOpenIM( +#if NeedNestedPrototypes + XLCd, Display *, XrmDatabase, char *, char * +#endif + ); + +Bool +_XInitDefaultIM(lcd) +XLCd lcd; +{ + if(lcd == (XLCd)NULL) + return False; + + lcd->methods->open_im = _XDefaultOpenIM; + lcd->methods->register_callback = NULL; + lcd->methods->unregister_callback = NULL; + return True; +} + +extern XOM _XDefaultOpenOM( +#if NeedFunctionPrototypes + XLCd, Display*, XrmDatabase, _Xconst char*, _Xconst char* +#endif + ); + +Bool +_XInitDefaultOM(lcd) + XLCd lcd; +{ + lcd->methods->open_om = _XDefaultOpenOM; + return True; +} diff --git a/src/xlibi18n/Xlcint.h b/src/xlibi18n/Xlcint.h new file mode 100644 index 00000000..60041e7e --- /dev/null +++ b/src/xlibi18n/Xlcint.h @@ -0,0 +1,1003 @@ +/* $Xorg: Xlcint.h,v 1.4 2001/02/09 02:03:38 xorgcvs Exp $ */ +/* + +Copyright 1991, 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 1990, 1991 by OMRON Corporation, NTT Software Corporation, + * and Nippon Telegraph and Telephone Corporation + * Copyright 1991 by the Open Software Foundation + * Copyright 1993 by the TOSHIBA Corp. + * Copyright 1993, 1994 by Sony Corporation + * Copyright 1993, 1994 by the FUJITSU LIMITED + * + * 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 names of OMRON, NTT Software, NTT, Open + * Software Foundation, and Sony Corporation not be used in advertising + * or publicity pertaining to distribution of the software without specific, + * written prior permission. OMRON, NTT Software, NTT, Open Software + * Foundation, and Sony Corporation make no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * OMRON, NTT SOFTWARE, NTT, OPEN SOFTWARE FOUNDATION, AND SONY + * CORPORATION DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING + * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT + * SHALL OMRON, NTT SOFTWARE, NTT, OPEN SOFTWARE FOUNDATION, OR SONY + * CORPORATION 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. + * + * Authors: Li Yuhong OMRON Corporation + * Tatsuya Kato NTT Software Corporation + * Hiroshi Kuribayashi OMRON Coproration + * Muneiyoshi Suzuki Nippon Telegraph and Telephone Co. + * + * M. Collins OSF + * Katsuhisa Yano TOSHIBA Corp. + * Makoto Wakamatsu Sony Corporation + * Takashi Fujiwara FUJITSU LIMITED + */ + + +#ifndef _XLCINT_H_ +#define _XLCINT_H_ + +#include <X11/Xresource.h> +#include <X11/Xutil.h> +#include "Xvarargs.h" + +typedef Bool (*XFilterEventProc)( +#if NeedFunctionPrototypes + Display* /* display */, + Window /* window */, + XEvent* /* event */, + XPointer /* client_data */ +#endif +); + +typedef struct _XIMFilter { + struct _XIMFilter *next; + Window window; + unsigned long event_mask; + int start_type, end_type; + XFilterEventProc filter; + XPointer client_data; +} XFilterEventRec, *XFilterEventList; + +typedef struct { + char *name; + XPointer value; +} XIMArg; + +#ifdef offsetof +#define XOffsetOf(s_type,field) offsetof(s_type,field) +#else +#define XOffsetOf(s_type,field) ((unsigned int)&(((s_type*)NULL)->field)) +#endif + +#define XIMNumber(arr) ((unsigned int) (sizeof(arr) / sizeof(arr[0]))) + +/* + * define secondary data structs which are part of Input Methods + * and Input Context + */ +typedef struct { + char *resource_name; /* Resource string */ + XrmQuark xrm_name; /* Resource name quark */ + int resource_size; /* Size in bytes of data */ + long resource_offset; /* Offset from base */ + unsigned short mode; /* Read Write Permission */ + unsigned short id; /* Input Method Protocol */ +} XIMResource, *XIMResourceList; + +/* + * data block describing the visual attributes associated with + * an input context + */ +typedef struct { + XRectangle area; + XRectangle area_needed; + XPoint spot_location; + Colormap colormap; + Atom std_colormap; + unsigned long foreground; + unsigned long background; + Pixmap background_pixmap; + XFontSet fontset; + int line_spacing; + Cursor cursor; + XIMCallback start_callback; + XIMCallback done_callback; + XIMCallback draw_callback; + XIMCallback caret_callback; + XIMPreeditState preedit_state; + XIMCallback state_notify_callback; +} ICPreeditAttributes, *ICPreeditAttributesPtr; + +typedef struct { + XRectangle area; + XRectangle area_needed; + Colormap colormap; + Atom std_colormap; + unsigned long foreground; + unsigned long background; + Pixmap background_pixmap; + XFontSet fontset; + int line_spacing; + Cursor cursor; + XIMCallback start_callback; + XIMCallback done_callback; + XIMCallback draw_callback; +} ICStatusAttributes, *ICStatusAttributesPtr; + +/* + * Methods for Xrm parsing + */ + +typedef void (*XmbInitProc)( +#if NeedFunctionPrototypes + XPointer /* state */ +#endif +); + +typedef char (*XmbCharProc)( +#if NeedFunctionPrototypes + XPointer /* state */, + char* /* str */, + int* /* lenp */ +#endif +); + +typedef void (*XmbFinishProc)( +#if NeedFunctionPrototypes + XPointer /* state */ +#endif +); + +typedef char* (*XlcNameProc)( +#if NeedFunctionPrototypes + XPointer /* state */ +#endif +); + +typedef void (*XrmDestroyProc)( +#if NeedFunctionPrototypes + XPointer /* state */ +#endif +); + +typedef struct { + XmbInitProc mbinit; + XmbCharProc mbchar; + XmbFinishProc mbfinish; + XlcNameProc lcname; + XrmDestroyProc destroy; +} XrmMethodsRec, *XrmMethods; + +typedef struct _XLCd *XLCd; /* need forward reference */ + +/* + * define an LC, it's methods, and data. + */ + +typedef void (*XCloseLCProc)( +#if NeedFunctionPrototypes + XLCd /* lcd */ +#endif +); + +typedef char* (*XlcMapModifiersProc)( +#if NeedFunctionPrototypes + XLCd /* lcd */, + char* /* user_mods */, + char* /* prog_mods */ +#endif +); + +typedef XOM (*XOpenOMProc)( +#if NeedFunctionPrototypes + XLCd /* lcd */, + Display* /* display */, + XrmDatabase /* rdb */, + _Xconst char* /* res_name */, + _Xconst char* /* res_class */ +#endif +); + +typedef XIM (*XOpenIMProc)( +#if NeedFunctionPrototypes + XLCd /* lcd */, + Display* /* display */, + XrmDatabase /* rdb */, + char* /* res_name */, + char* /* res_class */ +#endif +); + +typedef Bool (*XRegisterIMInstantiateCBProc)( +#if NeedFunctionPrototypes + XLCd /* lcd */, + Display* /* display */, + XrmDatabase /* rdb */, + char* /* res_name */, + char* /* res_class */, + XIMProc /* callback */, + XPointer* /* client_data */ +#endif +); + +typedef Bool (*XUnregisterIMInstantiateCBProc)( +#if NeedFunctionPrototypes + XLCd /* lcd */, + Display* /* display */, + XrmDatabase /* rdb */, + char* /* res_name */, + char* /* res_class */, + XIMProc /* callback */, + XPointer* /* client_data */ +#endif +); + +typedef XrmMethods (*XrmInitParseInfoProc)( +#if NeedFunctionPrototypes + XLCd /* lcd */, + XPointer* /* state */ +#endif +); + +typedef int (*XmbTextPropertyToTextListProc)( +#if NeedFunctionPrototypes + XLCd /* lcd */, + Display* /* display */, + XTextProperty* /* text_prop */, + char*** /* list_return */, + int* /* count_return */ +#endif +); + +typedef int (*XwcTextPropertyToTextListProc)( +#if NeedFunctionPrototypes + XLCd /* lcd */, + Display* /* display */, + XTextProperty* /* text_prop */, + wchar_t*** /* list_return */, + int* /* count_return */ +#endif +); + +typedef int (*XmbTextListToTextPropertyProc)( +#if NeedFunctionPrototypes + XLCd /* lcd */, + Display* /* display */, + char** /* list */, + int /* count */, + XICCEncodingStyle /* style */, + XTextProperty* /* text_prop_return */ +#endif +); + +typedef int (*XwcTextListToTextPropertyProc)( +#if NeedFunctionPrototypes + XLCd /* lcd */, + Display* /* display */, + wchar_t** /* list */, + int /* count */, + XICCEncodingStyle /* style */, + XTextProperty* /* text_prop_return */ +#endif +); + +typedef void (*XwcFreeStringListProc)( +#if NeedFunctionPrototypes + XLCd /* lcd */, + wchar_t** /* list */ +#endif +); + +typedef char* (*XDefaultStringProc)( +#if NeedFunctionPrototypes + XLCd /* lcd */ +#endif +); + +typedef struct { + XCloseLCProc close; + XlcMapModifiersProc map_modifiers; + XOpenOMProc open_om; + XOpenIMProc open_im; + XrmInitParseInfoProc init_parse_info; + XmbTextPropertyToTextListProc mb_text_prop_to_list; + XwcTextPropertyToTextListProc wc_text_prop_to_list; + XmbTextListToTextPropertyProc mb_text_list_to_prop; + XwcTextListToTextPropertyProc wc_text_list_to_prop; + XwcFreeStringListProc wc_free_string_list; + XDefaultStringProc default_string; + XRegisterIMInstantiateCBProc register_callback; + XUnregisterIMInstantiateCBProc unregister_callback; +} XLCdMethodsRec, *XLCdMethods; + + +typedef struct { + char* name; /* name of this LC */ + char* modifiers; /* modifiers of locale */ +} XLCdCoreRec, *XLCdCore; + + +typedef struct _XLCd { + XLCdMethods methods; /* methods of this LC */ + XLCdCore core; /* data of this LC */ + XPointer opaque; /* LDX specific data */ +} XLCdRec; + +typedef int XlcPosition; + +#define XlcHead 0 +#define XlcTail -1 + +typedef struct { + char *name; + XPointer value; +} XlcArg, *XlcArgList; + +typedef struct _XlcResource { + char *name; + XrmQuark xrm_name; + int size; + int offset; + unsigned long mask; +} XlcResource, *XlcResourceList; + +#define XlcCreateMask (1L<<0) +#define XlcDefaultMask (1L<<1) +#define XlcGetMask (1L<<2) +#define XlcSetMask (1L<<3) +#define XlcIgnoreMask (1L<<4) + +#define XlcNumber(arr) (sizeof(arr) / sizeof(arr[0])) + +typedef Status (*XCloseOMProc)( +#if NeedFunctionPrototypes + XOM /* om */ +#endif +); + +typedef char* (*XSetOMValuesProc)( +#if NeedFunctionPrototypes + XOM /* om */, + XlcArgList /* args */, + int /* num_args */ +#endif +); + +typedef char* (*XGetOMValuesProc)( +#if NeedFunctionPrototypes + XOM /* om */, + XlcArgList /* args */, + int /* num_args */ +#endif +); + +typedef XOC (*XCreateOCProc)( +#if NeedFunctionPrototypes + XOM /* om */, + XlcArgList /* args */, + int /* num_args */ +#endif +); + +typedef struct _XOMMethodsRec { + XCloseOMProc close; + XSetOMValuesProc set_values; + XGetOMValuesProc get_values; + XCreateOCProc create_oc; +} XOMMethodsRec, *XOMMethods; + +typedef struct _XOMCoreRec { + XLCd lcd; /* lcd */ + Display *display; /* display */ + XrmDatabase rdb; /* database */ + char *res_name; /* resource name */ + char *res_class; /* resource class */ + XOC oc_list; /* xoc list */ + XlcResourceList resources; /* xom resources */ + int num_resources; /* number of xom resources */ + XOMCharSetList required_charset; /* required charset list */ + XOMOrientation orientation_list; /* orientation list */ + Bool directional_dependent; /* directional-dependent */ + Bool contextual_drawing; /* contextual drawing */ + Bool context_dependent; /* context-dependent drawing */ +} XOMCoreRec, *XOMCore; + +typedef struct _XOM { + XOMMethods methods; + XOMCoreRec core; +} XOMRec; + +typedef void (*XDestroyOCProc)( +#if NeedFunctionPrototypes + XOC /* oc */ +#endif +); + +typedef char* (*XSetOCValuesProc)( +#if NeedFunctionPrototypes + XOC /* oc */, + XlcArgList /* args */, + int /* num_args */ +#endif +); + +typedef char* (*XGetOCValuesProc)( +#if NeedFunctionPrototypes + XOC /* oc */, + XlcArgList /* args */, + int /* num_args */ +#endif +); + +/* + * X Font Sets are an instantiable object, so we define it, the + * object itself, a method list and data + */ + +/* + * XFontSet object method list + */ + +typedef int (*XmbTextEscapementProc)( +#if NeedFunctionPrototypes + XFontSet /* font_set */, + _Xconst char* /* text */, + int /* text_len */ +#endif +); + +typedef int (*XmbTextExtentsProc)( +#if NeedFunctionPrototypes + XFontSet /* font_set */, + _Xconst char* /* text */, + int /* text_len */, + XRectangle* /* overall_ink_extents */, + XRectangle* /* overall_logical_extents */ +#endif +); + +typedef Status (*XmbTextPerCharExtentsProc)( +#if NeedFunctionPrototypes + XFontSet /* font_set */, + _Xconst char* /* text */, + int /* text_len */, + XRectangle* /* ink_extents_buffer */, + XRectangle* /* logical_extents_buffer */, + int /* buffer_size */, + int* /* num_chars */, + XRectangle* /* max_ink_extents */, + XRectangle* /* max_logical_extents */ +#endif +); + +typedef int (*XmbDrawStringProc)( +#if NeedFunctionPrototypes + Display* /* display */, + Drawable /* drawable */, + XFontSet /* font_set */, + GC /* gc */, + int /* x */, + int /* y */, + _Xconst char* /* text */, + int /* text_len */ +#endif +); + +typedef void (*XmbDrawImageStringProc)( +#if NeedFunctionPrototypes + Display* /* display */, + Drawable /* drawable */, + XFontSet /* font_set */, + GC /* gc */, + int /* x */, + int /* y */, + _Xconst char* /* text */, + int /* text_len */ +#endif +); + +typedef int (*XwcTextEscapementProc)( +#if NeedFunctionPrototypes + XFontSet /* font_set */, + _Xconst wchar_t* /* text */, + int /* text_len */ +#endif +); + +typedef int (*XwcTextExtentsProc)( +#if NeedFunctionPrototypes + XFontSet /* font_set */, + _Xconst wchar_t* /* text */, + int /* text_len */, + XRectangle* /* overall_ink_extents */, + XRectangle* /* overall_logical_extents */ +#endif +); + +typedef Status (*XwcTextPerCharExtentsProc)( +#if NeedFunctionPrototypes + XFontSet /* font_set */, + _Xconst wchar_t* /* text */, + int /* text_len */, + XRectangle* /* ink_extents_buffer */, + XRectangle* /* logical_extents_buffer */, + int /* buffer_size */, + int* /* num_chars */, + XRectangle* /* max_ink_extents */, + XRectangle* /* max_logical_extents */ +#endif +); + +typedef int (*XwcDrawStringProc)( +#if NeedFunctionPrototypes + Display* /* display */, + Drawable /* drawable */, + XFontSet /* font_set */, + GC /* gc */, + int /* x */, + int /* y */, + _Xconst wchar_t* /* text */, + int /* text_len */ +#endif +); + +typedef void (*XwcDrawImageStringProc)( +#if NeedFunctionPrototypes + Display* /* display */, + Drawable /* drawable */, + XFontSet /* font_set */, + GC /* gc */, + int /* x */, + int /* y */, + _Xconst wchar_t* /* text */, + int /* text_len */ +#endif +); + +typedef struct { + XDestroyOCProc destroy; + XSetOCValuesProc set_values; + XGetOCValuesProc get_values; + + /* multi-byte text drawing methods */ + + XmbTextEscapementProc mb_escapement; + XmbTextExtentsProc mb_extents; + XmbTextPerCharExtentsProc mb_extents_per_char; + XmbDrawStringProc mb_draw_string; + XmbDrawImageStringProc mb_draw_image_string; + + /* wide character text drawing methods */ + + XwcTextEscapementProc wc_escapement; + XwcTextExtentsProc wc_extents; + XwcTextPerCharExtentsProc wc_extents_per_char; + XwcDrawStringProc wc_draw_string; + XwcDrawImageStringProc wc_draw_image_string; +} XOCMethodsRec, *XOCMethods; + + +/* + * XOC independent data + */ + +typedef struct { + XOM om; /* XOM */ + XOC next; /* next XOC */ + XlcResourceList resources; /* xoc resources */ + int num_resources; /* number of xoc resources */ + char *base_name_list; /* base font name list */ + Bool om_automatic; /* OM Automatic */ + XOMFontInfo font_info; /* font info */ + XFontSetExtents font_set_extents; /* font set extents */ + char *default_string; /* default string */ + XOMCharSetList missing_list; /* missing charset list */ + XOrientation orientation; /* orientation */ + char *res_name; /* resource name */ + char *res_class; /* resource class */ +} XOCCoreRec, *XOCCore; + +typedef struct _XOC { + XOCMethods methods; + XOCCoreRec core; +} XOCRec; + + +/* current Ultrix compiler gets horribly confused */ +#if defined(FUNCPROTO) && defined(ultrix) +#undef NeedFunctionPrototypes +#endif + + +/* + * X Input Managers are an instantiable object, so we define it, the + * object itself, a method list and data. + */ + +/* + * an Input Manager object method list + */ +typedef struct { + Status (*close)( +#if NeedFunctionPrototypes + XIM +#endif + ); + char* (*set_values)( +#if NeedFunctionPrototypes + XIM, XIMArg* +#endif + ); + char* (*get_values)( +#if NeedFunctionPrototypes + XIM, XIMArg* +#endif + ); + XIC (*create_ic)( +#if NeedFunctionPrototypes + XIM, XIMArg* +#endif + ); + int (*ctstombs)( +#if NeedFunctionPrototypes + XIM, char*, int, char*, int, Status * +#endif + ); + int (*ctstowcs)( +#if NeedFunctionPrototypes + XIM, char*, int, wchar_t*, int, Status * +#endif + ); +} XIMMethodsRec, *XIMMethods; + +/* + * Input Manager LC independent data + */ +typedef struct { + XLCd lcd; /* LC of this input method */ + XIC ic_chain; /* list of ICs for this IM */ + + Display * display; /* display */ + XrmDatabase rdb; + char * res_name; + char * res_class; + + XIMValuesList *im_values_list; + XIMValuesList *ic_values_list; + XIMStyles *styles; + XIMCallback destroy_callback; + char * im_name; /* XIMMODIFIER name */ + XIMResourceList im_resources; /* compiled IM resource list */ + unsigned int im_num_resources; + XIMResourceList ic_resources; /* compiled IC resource list */ + unsigned int ic_num_resources; + Bool visible_position; +} XIMCoreRec, *XIMCore; + + + +/* + * An X Input Manager (IM). Implementations may need to extend this data + * structure to accomodate additional data, state information etc. + */ +typedef struct _XIM { + XIMMethods methods; /* method list of this IM */ + XIMCoreRec core; /* data of this IM */ +} XIMRec; + + + +/* + * X Input Contexts (IC) are an instantiable object, so we define it, the + * object itself, a method list and data for this object + */ + +/* + * Input Context method list + */ +typedef struct { + void (*destroy)( +#if NeedFunctionPrototypes + XIC +#endif + ); + void (*set_focus)( +#if NeedFunctionPrototypes + XIC +#endif + ); + void (*unset_focus)( +#if NeedFunctionPrototypes + XIC +#endif + ); + char* (*set_values)( +#if NeedFunctionPrototypes + XIC, XIMArg* +#endif + ); + char* (*get_values)( +#if NeedFunctionPrototypes + XIC, XIMArg* +#endif + ); + char* (*mb_reset)( +#if NeedFunctionPrototypes + XIC +#endif + ); + wchar_t* (*wc_reset)( +#if NeedFunctionPrototypes + XIC +#endif + ); + int (*mb_lookup_string)( +#if NeedFunctionPrototypes + XIC, XKeyEvent*, char*, int, KeySym*, Status* +#endif + ); + int (*wc_lookup_string)( +#if NeedFunctionPrototypes + XIC, XKeyEvent*, wchar_t*, int, KeySym*, Status* +#endif + ); +} XICMethodsRec, *XICMethods; + + +/* + * Input Context LC independent data + */ +typedef struct { + XIM im; /* XIM this IC belongs too */ + XIC next; /* linked list of ICs for IM */ + + Window client_window; /* window IM can use for */ + /* display or subwindows */ + XIMStyle input_style; /* IM's input style */ + Window focus_window; /* where key events go */ + unsigned long filter_events; /* event mask from IM */ + XIMCallback geometry_callback; /* client callback */ + char * res_name; + char * res_class; + + XIMCallback destroy_callback; + XIMCallback string_conversion_callback; + XIMStringConversionText string_conversion; + XIMResetState reset_state; + XIMHotKeyTriggers *hotkey; + XIMHotKeyState hotkey_state; + + ICPreeditAttributes preedit_attr; /* visuals of preedit area */ + ICStatusAttributes status_attr; /* visuals of status area */ +} XICCoreRec, *XICCore; + + +/* + * an Input Context. Implementations may need to extend this data + * structure to accomodate additional data, state information etc. + */ +typedef struct _XIC { + XICMethods methods; /* method list of this IC */ + XICCoreRec core; /* data of this IC */ +} XICRec; + +/* current Ultrix compiler gets horribly confused */ +#if !defined(NeedFunctionPrototypes) && defined(FUNCPROTO) +#define NeedFunctionPrototypes 1 +#endif + +typedef XLCd (*XLCdLoadProc)( +#if NeedFunctionPrototypes + char* +#endif +); + +_XFUNCPROTOBEGIN + +extern XLCd _XOpenLC( +#if NeedFunctionPrototypes + char* /* name */ +#endif +); + +extern void _XCloseLC( +#if NeedFunctionPrototypes + XLCd /* lcd */ +#endif +); + +extern XLCd _XlcCurrentLC( +#if NeedFunctionPrototypes + void +#endif +); + +extern Bool _XlcValidModSyntax( +#if NeedFunctionPrototypes + char* /* mods */, + char** /* valid */ +#endif +); + +extern char *_XlcDefaultMapModifiers( +#if NeedFunctionPrototypes + XLCd /* lcd */, + char* /* user_mods */, + char* /* prog_mods */ +#endif +); + +extern void _XIMCompileResourceList( +#if NeedFunctionPrototypes + XIMResourceList /* res */, + unsigned int /* num_res */ +#endif +); + +extern void _XCopyToArg( +#if NeedFunctionPrototypes + XPointer /* src */, + XPointer* /* dst */, + unsigned int /* size */ +#endif +); + +extern char ** _XParseBaseFontNameList( +#if NeedFunctionPrototypes + char* /* str */, + int* /* num */ +#endif +); + +extern XrmMethods _XrmInitParseInfo( +#if NeedFunctionPrototypes + XPointer* /* statep */ +#endif +); + +extern void _XRegisterFilterByMask( +#if NeedFunctionPrototypes + Display* /* dpy */, + Window /* window */, + unsigned long /* event_mask */, + Bool (*)( +#if NeedNestedPrototypes + Display* /* display */, + Window /* window */, + XEvent* /* event */, + XPointer /* client_data */ +#endif + ) /* filter */, + XPointer /* client_data */ +#endif +); + +extern void _XRegisterFilterByType( +#if NeedFunctionPrototypes + Display* /* dpy */, + Window /* window */, + int /* start_type */, + int /* end_type */, + Bool (*)( +#if NeedNestedPrototypes + Display* /* display */, + Window /* window */, + XEvent* /* event */, + XPointer /* client_data */ +#endif + ) /* filter */, + XPointer /* client_data */ +#endif +); + +extern void _XUnregisterFilter( +#if NeedFunctionPrototypes + Display* /* dpy */, + Window /* window */, + Bool (*)( +#if NeedNestedPrototypes + Display* /* display */, + Window /* window */, + XEvent* /* event */, + XPointer /* client_data */ +#endif + ) /* filter */, + XPointer /* client_data */ +#endif +); + +extern void _XlcCountVaList( +#if NeedFunctionPrototypes + va_list /* var */, + int* /* count_return */ +#endif +); + +extern void _XlcVaToArgList( +#if NeedFunctionPrototypes + va_list /* var */, + int /* count */, + XlcArgList* /* args_return */ +#endif +); + +extern void _XlcCompileResourceList( +#if NeedFunctionPrototypes + XlcResourceList /* resources */, + int /* num_resources */ +#endif +); + +extern char *_XlcGetValues( +#if NeedFunctionPrototypes + XPointer /* base */, + XlcResourceList /* resources */, + int /* num_resources */, + XlcArgList /* args */, + int /* num_args */, + unsigned long /* mask */ +#endif +); + +extern char *_XlcSetValues( +#if NeedFunctionPrototypes + XPointer /* base */, + XlcResourceList /* resources */, + int /* num_resources */, + XlcArgList /* args */, + int /* num_args */, + unsigned long /* mask */ +#endif +); + +extern Bool _XlcAddLoader( +#if NeedFunctionPrototypes + XLCdLoadProc /* proc */, + XlcPosition /* position */ +#endif +); + +extern void _XlcRemoveLoader( +#if NeedFunctionPrototypes + XLCdLoadProc /* proc */ +#endif +); + +_XFUNCPROTOEND + +#endif /* _XLCINT_H_ */ diff --git a/src/xlibi18n/lcCT.c b/src/xlibi18n/lcCT.c new file mode 100644 index 00000000..5dd2ddcc --- /dev/null +++ b/src/xlibi18n/lcCT.c @@ -0,0 +1,909 @@ +/* $Xorg: lcCT.c,v 1.4 2000/08/17 19:45:16 cpqbld Exp $ */ +/* + * Copyright 1992, 1993 by TOSHIBA Corp. + * + * 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 TOSHIBA not be used in advertising + * or publicity pertaining to distribution of the software without specific, + * written prior permission. TOSHIBA make no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * TOSHIBA DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING + * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL + * TOSHIBA 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. + * + * Author: Katsuhisa Yano TOSHIBA Corp. + * mopi@osa.ilab.toshiba.co.jp + */ +/* + * Copyright 1995 by FUJITSU LIMITED + * This is source code modified by FUJITSU LIMITED under the Joint + * Development Agreement for the CDE/Motif PST. + * + * Modifier: Takanori Tateno FUJITSU LIMITED + * + */ + +#include "Xlibint.h" +#include "XlcPubI.h" +#include <X11/Xos.h> +#include <stdio.h> + +typedef struct _StateRec { + XlcCharSet charset; + XlcCharSet GL_charset; + XlcCharSet GR_charset; + XlcCharSet ext_seg_charset; + int ext_seg_left; +} StateRec, *State; + +typedef struct _CTDataRec { + char *name; + char *encoding; /* Compound Text encoding */ +} CTDataRec, *CTData; + +typedef struct _CTInfoRec { + XlcCharSet charset; + int encoding_len; + char *encoding; /* Compound Text encoding */ + int ext_segment_len; + char *ext_segment; /* extended segment */ + struct _CTInfoRec *next; +} CTInfoRec, *CTInfo; + +static CTDataRec default_ct_data[] = +{ + { "ISO8859-1:GL", "\033(B" }, + { "ISO8859-1:GR", "\033-A" }, + { "ISO8859-2:GR", "\033-B" }, + { "ISO8859-3:GR", "\033-C" }, + { "ISO8859-4:GR", "\033-D" }, + { "ISO8859-7:GR", "\033-F" }, + { "ISO8859-6:GR", "\033-G" }, + { "ISO8859-8:GR", "\033-H" }, + { "ISO8859-5:GR", "\033-L" }, + { "ISO8859-9:GR", "\033-M" }, + { "ISO8859-10:GR", "\033-V" }, + { "JISX0201.1976-0:GL", "\033(J" }, + { "JISX0201.1976-0:GR", "\033)I" }, + + { "GB2312.1980-0:GL", "\033$(A" }, + { "GB2312.1980-0:GR", "\033$)A" }, + { "JISX0208.1983-0:GL", "\033$(B" }, + { "JISX0208.1983-0:GR", "\033$)B" }, + { "KSC5601.1987-0:GL", "\033$(C" }, + { "KSC5601.1987-0:GR", "\033$)C" }, +#ifdef notdef + { "JISX0212.1990-0:GL", "\033$(D" }, + { "JISX0212.1990-0:GR", "\033$)D" }, + { "CNS11643.1986-1:GL", "\033$(G" }, + { "CNS11643.1986-1:GR", "\033$)G" }, + { "CNS11643.1986-2:GL", "\033$(H" }, + { "CNS11643.1986-2:GR", "\033$)H" }, +#endif + { "TIS620.2533-1:GR", "\033-T"}, + { "ISO10646-1", "\033%B"}, + /* Non-Standard Character Set Encodings */ + { "KOI8-R:GR", "\033%/1\200\210koi8-r\002"}, + { "FCD8859-15:GR", "\033%/1\200\213fcd8859-15\002"}, +} ; + +#define XctC0 0x0000 +#define XctHT 0x0009 +#define XctNL 0x000a +#define XctESC 0x001b +#define XctGL 0x0020 +#define XctC1 0x0080 +#define XctCSI 0x009b +#define XctGR 0x00a0 + +#define XctCntrlFunc 0x0023 +#define XctMB 0x0024 +#define XctOtherCoding 0x0025 +#define XctGL94 0x0028 +#define XctGR94 0x0029 +#define XctGR96 0x002d +#define XctNonStandard 0x002f +#define XctIgnoreExt 0x0030 +#define XctNotIgnoreExt 0x0031 +#define XctLeftToRight 0x0031 +#define XctRightToLeft 0x0032 +#define XctDirection 0x005d +#define XctDirectionEnd 0x005d + +#define XctGL94MB 0x2428 +#define XctGR94MB 0x2429 +#define XctExtSeg 0x252f +#define XctOtherSeg 0x2f00 + +#define XctESCSeq 0x1b00 +#define XctCSISeq 0x9b00 + +#define SKIP_I(str) while (*(str) >= 0x20 && *(str) <= 0x2f) (str)++; +#define SKIP_P(str) while (*(str) >= 0x30 && *(str) <= 0x3f) (str)++; + +typedef struct { + XlcSide side; + int char_size; + int set_size; + int ext_seg_length; + int version; + CTInfo ct_info; +} CTParseRec, *CTParse; + +CTDataRec *default_ct_data_list() +{ + return(default_ct_data); +} + +size_t default_ct_data_list_num() +{ + size_t num = sizeof(default_ct_data) / sizeof(CTDataRec); + return(num); +} + +static CTInfo ct_list = NULL; + +static CTInfo +_XlcGetCTInfoFromEncoding(encoding, length) + register char *encoding; + register int length; +{ + register CTInfo ct_info; + + for (ct_info = ct_list; ct_info; ct_info = ct_info->next) { + if (length >= ct_info->encoding_len) { + if (ct_info->ext_segment) { + if (!strncmp(ct_info->encoding, encoding, 4) && + !strncmp(ct_info->ext_segment, encoding + 6, + ct_info->ext_segment_len)) + return ct_info; + } else if (!strncmp(ct_info->encoding, encoding, + ct_info->encoding_len)) { + return ct_info; + } + } + } + + return (CTInfo) NULL; +} + +static unsigned int +_XlcParseCT(parse, text, length) + register CTParse parse; + char **text; + int *length; +{ + unsigned int ret = 0; + unsigned char ch; + register unsigned char *str = (unsigned char *) *text; + + bzero((char *) parse, sizeof(CTParseRec)); + + switch (ch = *str++) { + case XctESC: + if (*str == XctOtherCoding && *(str + 1) == XctNonStandard + && *(str + 2) >= 0x30 && *(str + 2) <= 0x3f && *length >= 6) { + + /* non-standard encodings */ + parse->side = XlcGLGR; + parse->set_size = 0; + str += 2; + if (*str <= 0x34) { + parse->char_size = *str - 0x30; + if (parse->char_size == 0) parse->char_size = 1; + ret = XctExtSeg; + parse->ct_info = _XlcGetCTInfoFromEncoding(*text, *length); + } else + ret = XctOtherSeg; + str++; + parse->ext_seg_length = (*str - 128) * 128 + *(str + 1) - 128; + str += 2; + + goto done; + } else if (*str == XctCntrlFunc && *length >= 4 && + *(str + 1) >= 0x20 && *(str + 1) <= 0x2f && + (*(str + 2) == XctIgnoreExt || + *(str + 2) == XctNotIgnoreExt)) { + + /* ignore extension or not */ + str++; + parse->version = *str++ - 0x20; + ret = *str++; + + goto done; + } + + if (*str == XctMB) { /* multiple-byte sets */ + parse->char_size = 2; + str++; + } else + parse->char_size = 1; + + switch (*str) { + case XctGL94: + parse->side = XlcGL; + parse->set_size = 94; + ret = (parse->char_size == 1) ? XctGL94 : XctGL94MB; + break; + case XctGR94: + parse->side = XlcGR; + parse->set_size = 94; + ret = (parse->char_size == 1) ? XctGR94 : XctGR94MB; + break; + case XctGR96: + if (parse->char_size == 1) { + parse->side = XlcGR; + parse->set_size = 96; + ret = XctGR96; + } + break; + } + if (ret) { + str++; + if (*str >= 0x24 && *str <= 0x2f) { /* non-standard */ + ret = 0; + str++; + } + } + + SKIP_I(str) + + if (ret && *str < 0x40) /* non-standard */ + ret = 0; + + if (*str < 0x30 || *str > 0x7e || (char *) str - *text >= *length) + break; + + if (ret == 0) + ret = XctESCSeq; + else { + if (parse->char_size == 2) { + if (*str >= 0x70) + parse->char_size = 4; + else if (*str >= 0x60) + parse->char_size = 3; + } + parse->ct_info = _XlcGetCTInfoFromEncoding(*text, *length); + } + str++; + goto done; + case XctCSI: + /* direction */ + if (*str == XctLeftToRight && *(str + 1) == XctDirection) { + ret = XctLeftToRight; + str += 2; + goto done; + } else if (*str == XctRightToLeft && *(str + 1) == XctDirection) { + ret = XctRightToLeft; + str += 2; + goto done; + } else if (*str == XctDirectionEnd) { + ret = XctDirectionEnd; + str++; + goto done; + } + + SKIP_P(str) + SKIP_I(str) + + if (*str < 0x40 && *str > 0x7e) + break; + + ret = XctCSISeq; + str++; + goto done; + } + + if (ch & 0x80) { + if (ch < 0xa0) + ret = XctC1; + else + ret = XctGR; + } else { + if (ch == XctHT || ch == XctNL) + ret = ch; + else if (ch < 0x20) + ret = XctC0; + else + ret = XctGL; + } + + return ret; + +done: + *length -= (char *) str - *text; + *text = (char *) str; + + return ret; +} + +XlcCharSet +_XlcAddCT(name, encoding) + char *name; + char *encoding; +{ + CTInfo ct_info; + XlcCharSet charset; + CTParseRec parse; + char *ct_ptr = encoding; + int length; + unsigned int type; + + length = strlen(encoding); + + switch (type = _XlcParseCT(&parse, &ct_ptr, &length)) { + case XctExtSeg: + case XctGL94: + case XctGL94MB: + case XctGR94: + case XctGR94MB: + case XctGR96: + if (parse.ct_info) /* existed */ + return parse.ct_info->charset; + break; + default: + return (XlcCharSet) NULL; + } + + charset = _XlcCreateDefaultCharSet(name, encoding); + if (charset == NULL) + return (XlcCharSet) NULL; + _XlcAddCharSet(charset); + + ct_info = (CTInfo) Xmalloc(sizeof(CTInfoRec)); + if (ct_info == NULL) + return (XlcCharSet) NULL; + + ct_info->charset = charset; + ct_info->encoding = charset->ct_sequence; + ct_info->encoding_len = strlen(ct_info->encoding); + if (type == XctExtSeg) { + ct_info->ext_segment = ct_info->encoding + 6; + ct_info->ext_segment_len = strlen(ct_info->ext_segment); + } else { + ct_info->ext_segment = NULL; + ct_info->ext_segment_len = 0; + } + ct_info->next = ct_list; + ct_list = ct_info; + + return charset; +} + +static CTInfo +_XlcGetCTInfoFromCharSet(charset) + register XlcCharSet charset; +{ + register CTInfo ct_info; + + for (ct_info = ct_list; ct_info; ct_info = ct_info->next) + if (ct_info->charset == charset) + return ct_info; + + return (CTInfo) NULL; +} + +Bool +_XlcParseCharSet(charset) + XlcCharSet charset; +{ + CTParseRec parse; + char *ptr, *bufp, buf[BUFSIZ]; + int length; + + if (charset->ct_sequence == NULL) + return False; + + ptr = charset->ct_sequence; + length = strlen(ptr); + + (void) _XlcParseCT(&parse, &ptr, &length); + + if (charset->name) { + charset->xrm_name = XrmStringToQuark(charset->name); + + if ((length = strlen (charset->name)) < sizeof buf) bufp = buf; + else bufp = Xmalloc (length + 1); + + if (bufp == NULL) return False; + strcpy(bufp, charset->name); + if ((ptr = strchr(bufp, ':'))) + *ptr = '\0'; + charset->xrm_encoding_name = XrmStringToQuark(bufp); + if (bufp != buf) Xfree (bufp); + charset->encoding_name = XrmQuarkToString(charset->xrm_encoding_name); + } else { + charset->xrm_name = 0; + charset->encoding_name = NULL; + charset->xrm_encoding_name = 0; + } + + charset->side = parse.side; + charset->char_size = parse.char_size; + charset->set_size = parse.set_size; + + return True; +} + +static void init_converter(); + +Bool +_XlcInitCTInfo() +{ + register XlcCharSet charset; + register CTData ct_data; + register int num; + + if (ct_list == NULL) { + num = sizeof(default_ct_data) / sizeof(CTDataRec); + for (ct_data = default_ct_data; num-- > 0; ct_data++) { + charset = _XlcAddCT(ct_data->name, ct_data->encoding); + if (charset == NULL) + continue; + } + init_converter(); + } + + return True; +} + + +static int +_XlcCheckCTSequence(state, ctext, ctext_len) + State state; + char **ctext; + int *ctext_len; +{ + XlcCharSet charset; + CTParseRec parse; + CTInfo ct_info; + int length; + + _XlcParseCT(&parse, ctext, ctext_len); + + ct_info = parse.ct_info; + if (parse.ext_seg_length > 0) { /* XctExtSeg or XctOtherSeg */ + if (ct_info) { + length = ct_info->ext_segment_len; + *ctext += length; + *ctext_len -= length; + state->ext_seg_left = parse.ext_seg_length - length; + state->ext_seg_charset = ct_info->charset; + } else { + state->ext_seg_left = parse.ext_seg_length; + state->ext_seg_charset = NULL; + } + } else if (ct_info) { + if ((charset = ct_info->charset)) { + if (charset->side == XlcGL) + state->GL_charset = charset; + else if (charset->side == XlcGR) + state->GR_charset = charset; + } + } + + return 0; +} + + +static void +init_state(conv) + XlcConv conv; +{ + State state = (State) conv->state; + static XlcCharSet GL_charset = NULL; + static XlcCharSet GR_charset = NULL; + + if (GL_charset == NULL) { + GL_charset = _XlcGetCharSet("ISO8859-1:GL"); + GR_charset = _XlcGetCharSet("ISO8859-1:GR"); + } + + state->GL_charset = state->charset = GL_charset; + state->GR_charset = GR_charset; + state->ext_seg_charset = NULL; + state->ext_seg_left = 0; +} + +static int +cttocs(conv, from, from_left, to, to_left, args, num_args) + XlcConv conv; + XPointer *from; + int *from_left; + XPointer *to; + int *to_left; + XPointer *args; + int num_args; +{ + register State state = (State) conv->state; + register unsigned char ch; + int length; + XlcCharSet charset = NULL; + char *ctptr, *bufptr; + int ctext_len, buf_len; + + ctptr = *((char **) from); + bufptr = *((char **) to); + ctext_len = *from_left; + buf_len = *to_left; + + while (ctext_len > 0 && buf_len > 0) { + if (state->ext_seg_left > 0) { + length = min(state->ext_seg_left, ctext_len); + length = min(length, buf_len); + + ctext_len -= length; + state->ext_seg_left -= length; + + if (state->ext_seg_charset) { + charset = state->ext_seg_charset; + buf_len -= length; + if (charset->side == XlcGL) { + while (length-- > 0) + *bufptr++ = *ctptr++ & 0x7f; + } else if (charset->side == XlcGR) { + while (length-- > 0) + *bufptr++ = *ctptr++ | 0x80; + } else { + while (length-- > 0) + *bufptr++ = *ctptr++; + } + + if (state->ext_seg_left < 1) + state->ext_seg_charset = NULL; + } + break; + } + ch = *((unsigned char *) ctptr); + if (ch == 0x1b || ch == 0x9b) { + length = _XlcCheckCTSequence(state, &ctptr, &ctext_len); + if (length < 0) + return -1; + if (state->ext_seg_left > 0 && charset) + break; + } else { + if (charset) { + if (charset != (ch & 0x80 ? state->GR_charset : + state->GL_charset)) + break; + } else + charset = ch & 0x80 ? state->GR_charset : state->GL_charset; + + if ((ch < 0x20 && ch != '\0' && ch != '\n' && ch != '\t') || + (ch >= 0x80 && ch < 0xa0)) + return -1; + + *bufptr++ = *ctptr++; + ctext_len--; + buf_len--; + } + } + + if (charset) + state->charset = charset; + if (num_args > 0) + *((XlcCharSet *) args[0]) = state->charset; + + *from_left -= ctptr - *((char **) from); + *from = (XPointer) ctptr; + + *to_left -= bufptr - *((char **) to); + *to = (XPointer) bufptr; + + return 0; +} + +static int +cstoct(conv, from, from_left, to, to_left, args, num_args) + XlcConv conv; + XPointer *from; + int *from_left; + XPointer *to; + int *to_left; + XPointer *args; + int num_args; +{ + State state = (State) conv->state; + XlcSide side; + unsigned char min_ch, max_ch; + register unsigned char ch; + int length; + CTInfo ct_info; + XlcCharSet charset; + char *csptr, *ctptr; + int csstr_len, ct_len; + + if (num_args < 1) + return -1; + + csptr = *((char **) from); + ctptr = *((char **) to); + csstr_len = *from_left; + ct_len = *to_left; + + charset = (XlcCharSet) args[0]; + + ct_info = _XlcGetCTInfoFromCharSet(charset); + if (ct_info == NULL) + return -1; + + side = charset->side; + + if (ct_info->ext_segment) { + if (charset != state->ext_seg_charset && state->ext_seg_left < 1) { + length = ct_info->encoding_len; + if (ct_len < length) + return -1; + strcpy(ctptr, ct_info->encoding); + ctptr[4] = ((ct_info->ext_segment_len + csstr_len) / 128) | 0x80; + ctptr[5] = ((ct_info->ext_segment_len + csstr_len) % 128) | 0x80; + ctptr += length; + ct_len -= length; + state->ext_seg_left = csstr_len; + } + length = min(state->ext_seg_left, csstr_len); + state->ext_seg_left -= length; + + if (side == XlcGL) { + while (length-- > 0) + *ctptr++ = *csptr++ & 0x7f; + } else if (side == XlcGR) { + while (length-- > 0) + *ctptr++ = *csptr++ | 0x80; + } else { + while (length-- > 0) + *ctptr++ = *csptr++; + } + state->ext_seg_charset = (state->ext_seg_left > 0) ? charset : NULL; + } else { + if ((side == XlcGR && charset != state->GR_charset) || + (side == XlcGL && charset != state->GL_charset)) { + + ct_len -= ct_info->encoding_len; + if (ct_len < 0) + return -1; + strcpy(ctptr, ct_info->encoding); + ctptr += ct_info->encoding_len; + } + + min_ch = 0x20; + max_ch = 0x7f; + + if (charset->set_size == 94) { + max_ch--; + if (charset->char_size > 1 || side == XlcGR) + min_ch++; + } + + while (csstr_len > 0 && ct_len > 0) { + ch = *((unsigned char *) csptr++) & 0x7f; + if (ch < min_ch || ch > max_ch) + if (ch != 0x00 && ch != 0x09 && ch != 0x0a && ch != 0x1b) + continue; /* XXX */ + if (side == XlcGL) + *ctptr++ = ch & 0x7f; + else if (side == XlcGR) + *ctptr++ = ch | 0x80; + else + *ctptr++ = ch; + csstr_len--; + ct_len--; + } + if (side == XlcGR) + state->GR_charset = charset; + else if (side == XlcGL) + state->GL_charset = charset; + } + + *from_left -= csptr - *((char **) from); + *from = (XPointer) csptr; + + *to_left -= ctptr - *((char **) to); + *to = (XPointer) ctptr; + + return 0; +} + +static int +strtocs(conv, from, from_left, to, to_left, args, num_args) + XlcConv conv; + XPointer *from; + int *from_left; + XPointer *to; + int *to_left; + XPointer *args; + int num_args; +{ + State state = (State) conv->state; + register char *src, *dst; + unsigned char side; + register int length; + + src = (char *) *from; + dst = (char *) *to; + + length = min(*from_left, *to_left); + side = *((unsigned char *) src) & 0x80; + + while (side == (*((unsigned char *) src) & 0x80) && length-- > 0) + *dst++ = *src++; + + *from_left -= src - (char *) *from; + *from = (XPointer) src; + *to_left -= dst - (char *) *to; + *to = (XPointer) dst; + + if (num_args > 0) + *((XlcCharSet *)args[0]) = side ? state->GR_charset : state->GL_charset; + + return 0; +} + +static int +cstostr(conv, from, from_left, to, to_left, args, num_args) + XlcConv conv; + XPointer *from; + int *from_left; + XPointer *to; + int *to_left; + XPointer *args; + int num_args; +{ + State state = (State) conv->state; + char *csptr, *string_ptr; + int csstr_len, str_len; + unsigned char ch; + int unconv_num = 0; + + if (num_args < 1 || (state->GL_charset != (XlcCharSet) args[0] && + state->GR_charset != (XlcCharSet) args[0])) + return -1; + + csptr = *((char **) from); + string_ptr = *((char **) to); + csstr_len = *from_left; + str_len = *to_left; + + while (csstr_len-- > 0 && str_len > 0) { + ch = *((unsigned char *) csptr++); + if ((ch < 0x20 && ch != 0x00 && ch != 0x09 && ch != 0x0a) || + ch == 0x7f || ((ch & 0x80) && ch < 0xa0)) { + unconv_num++; + continue; + } + *((unsigned char *) string_ptr++) = ch; + str_len--; + } + + *from_left -= csptr - *((char **) from); + *from = (XPointer) csptr; + + *to_left -= string_ptr - *((char **) to); + *to = (XPointer) string_ptr; + + return unconv_num; +} + + +static void +close_converter(conv) + XlcConv conv; +{ + if (conv->state) + Xfree((char *) conv->state); + + Xfree((char *) conv); +} + +static XlcConv +create_conv(methods) + XlcConvMethods methods; +{ + register XlcConv conv; + + conv = (XlcConv) Xmalloc(sizeof(XlcConvRec)); + if (conv == NULL) + return (XlcConv) NULL; + + conv->state = (XPointer) Xmalloc(sizeof(StateRec)); + if (conv->state == NULL) + goto err; + + conv->methods = methods; + + init_state(conv); + + return conv; + +err: + close_converter(conv); + + return (XlcConv) NULL; +} + +static XlcConvMethodsRec cttocs_methods = { + close_converter, + cttocs, + init_state +} ; + +static XlcConv +open_cttocs(from_lcd, from_type, to_lcd, to_type) + XLCd from_lcd; + char *from_type; + XLCd to_lcd; + char *to_type; +{ + return create_conv(&cttocs_methods); +} + +static XlcConvMethodsRec cstoct_methods = { + close_converter, + cstoct, + init_state +} ; + +static XlcConv +open_cstoct(from_lcd, from_type, to_lcd, to_type) + XLCd from_lcd; + char *from_type; + XLCd to_lcd; + char *to_type; +{ + return create_conv(&cstoct_methods); +} + +static XlcConvMethodsRec strtocs_methods = { + close_converter, + strtocs, + init_state +} ; + +static XlcConv +open_strtocs(from_lcd, from_type, to_lcd, to_type) + XLCd from_lcd; + char *from_type; + XLCd to_lcd; + char *to_type; +{ + return create_conv(&strtocs_methods); +} + +static XlcConvMethodsRec cstostr_methods = { + close_converter, + cstostr, + init_state +} ; + +static XlcConv +open_cstostr(from_lcd, from_type, to_lcd, to_type) + XLCd from_lcd; + char *from_type; + XLCd to_lcd; + char *to_type; +{ + return create_conv(&cstostr_methods); +} + +static void +init_converter() +{ + _XlcSetConverter((XLCd) NULL, XlcNCompoundText, (XLCd) NULL, XlcNCharSet, + open_cttocs); + _XlcSetConverter((XLCd) NULL, XlcNString, (XLCd) NULL, XlcNCharSet, + open_strtocs); + + _XlcSetConverter((XLCd) NULL, XlcNCharSet, (XLCd) NULL, XlcNCompoundText, + open_cstoct); + _XlcSetConverter((XLCd) NULL, XlcNCharSet, (XLCd) NULL, XlcNString, + open_cstostr); +} diff --git a/src/xlibi18n/lcCharSet.c b/src/xlibi18n/lcCharSet.c new file mode 100644 index 00000000..e9a376b0 --- /dev/null +++ b/src/xlibi18n/lcCharSet.c @@ -0,0 +1,164 @@ +/* $Xorg: lcCharSet.c,v 1.3 2000/08/17 19:45:16 cpqbld Exp $ */ +/* + * Copyright 1992, 1993 by TOSHIBA Corp. + * + * 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 TOSHIBA not be used in advertising + * or publicity pertaining to distribution of the software without specific, + * written prior permission. TOSHIBA make no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * TOSHIBA DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING + * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL + * TOSHIBA 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. + * + * Author: Katsuhisa Yano TOSHIBA Corp. + * mopi@osa.ilab.toshiba.co.jp + */ + +#include <stdio.h> +#include "Xlibint.h" +#include "XlcPublic.h" + +#if NeedVarargsPrototypes +char * +_XlcGetCSValues(XlcCharSet charset, ...) +#else +char * +_XlcGetCSValues(charset, va_alist) + XlcCharSet charset; + va_dcl +#endif +{ + va_list var; + XlcArgList args; + char *ret; + int num_args; + + Va_start(var, charset); + _XlcCountVaList(var, &num_args); + va_end(var); + + Va_start(var, charset); + _XlcVaToArgList(var, num_args, &args); + va_end(var); + + if (args == (XlcArgList) NULL) + return (char *) NULL; + + if (charset->get_values) + ret = (*charset->get_values)(charset, args, num_args); + else + ret = args->name; + + Xfree(args); + + return ret; +} + +typedef struct _XlcCharSetListRec { + XlcCharSet charset; + struct _XlcCharSetListRec *next; +} XlcCharSetListRec, *XlcCharSetList; + +static XlcCharSetList charset_list = NULL; + +XlcCharSet +_XlcGetCharSet(name) + char *name; +{ + XlcCharSetList list; + XrmQuark xrm_name; + + xrm_name = XrmStringToQuark(name); + + for (list = charset_list; list; list = list->next) { + if (xrm_name == list->charset->xrm_name) + return (XlcCharSet) list->charset; + } + + return (XlcCharSet) NULL; +} + +Bool +_XlcAddCharSet(charset) + XlcCharSet charset; +{ + XlcCharSetList list; + + if (_XlcGetCharSet(charset->name)) + return False; + + list = (XlcCharSetList) Xmalloc(sizeof(XlcCharSetListRec)); + if (list == NULL) + return False; + + list->charset = charset; + list->next = charset_list; + charset_list = list; + + return True; +} + +static XlcResource resources[] = { + { XlcNName, NULLQUARK, sizeof(char *), + XOffsetOf(XlcCharSetRec, name), XlcGetMask }, + { XlcNEncodingName, NULLQUARK, sizeof(char *), + XOffsetOf(XlcCharSetRec, encoding_name), XlcGetMask }, + { XlcNSide, NULLQUARK, sizeof(XlcSide), + XOffsetOf(XlcCharSetRec, side), XlcGetMask }, + { XlcNCharSize, NULLQUARK, sizeof(int), + XOffsetOf(XlcCharSetRec, char_size), XlcGetMask }, + { XlcNSetSize, NULLQUARK, sizeof(int), + XOffsetOf(XlcCharSetRec, set_size), XlcGetMask }, + { XlcNControlSequence, NULLQUARK, sizeof(char *), + XOffsetOf(XlcCharSetRec, ct_sequence), XlcGetMask } +}; + +static char * +get_values(charset, args, num_args) + register XlcCharSet charset; + register XlcArgList args; + register int num_args; +{ + if (resources[0].xrm_name == NULLQUARK) + _XlcCompileResourceList(resources, XlcNumber(resources)); + + return _XlcGetValues((XPointer) charset, resources, XlcNumber(resources), + args, num_args, XlcGetMask); +} + +XlcCharSet +_XlcCreateDefaultCharSet(name, ct_sequence) + char *name; + char *ct_sequence; +{ + XlcCharSet charset; + + charset = (XlcCharSet) Xmalloc(sizeof(XlcCharSetRec)); + if (charset == NULL) + return (XlcCharSet) NULL; + bzero((char *) charset, sizeof(XlcCharSetRec)); + + charset->name = (char *) Xmalloc(strlen(name) + strlen(ct_sequence) + 2); + if (charset->name == NULL) { + Xfree((char *) charset); + return (XlcCharSet) NULL; + } + strcpy(charset->name, name); + charset->ct_sequence = charset->name + strlen(name) + 1; + strcpy(charset->ct_sequence, ct_sequence); + charset->get_values = get_values; + + _XlcParseCharSet(charset); + + return (XlcCharSet) charset; +} diff --git a/src/xlibi18n/lcConv.c b/src/xlibi18n/lcConv.c new file mode 100644 index 00000000..f03adcc6 --- /dev/null +++ b/src/xlibi18n/lcConv.c @@ -0,0 +1,332 @@ +/* $Xorg: lcConv.c,v 1.4 2000/08/17 19:45:17 cpqbld Exp $ */ +/* + * Copyright 1992, 1993 by TOSHIBA Corp. + * + * 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 TOSHIBA not be used in advertising + * or publicity pertaining to distribution of the software without specific, + * written prior permission. TOSHIBA make no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * TOSHIBA DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING + * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL + * TOSHIBA 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. + * + * Author: Katsuhisa Yano TOSHIBA Corp. + * mopi@osa.ilab.toshiba.co.jp + */ + +#include "Xlibint.h" +#include "XlcPubI.h" +#include <stdio.h> + +typedef XlcConv (*XlcConverter)(); + +typedef struct _XlcConverterListRec { + XLCd from_lcd; + char *from; + XrmQuark from_type; + XLCd to_lcd; + char *to; + XrmQuark to_type; + XlcConverter converter; + struct _XlcConverterListRec *next; +} XlcConverterListRec, *XlcConverterList; + +static XlcConverterList conv_list = NULL; + +static void +close_converter(conv) + XlcConv conv; +{ + (*conv->methods->close)(conv); +} + +static XlcConv +get_converter(from_lcd, from_type, to_lcd, to_type) + XLCd from_lcd; + XrmQuark from_type; + XLCd to_lcd; + XrmQuark to_type; +{ + register XlcConverterList list, prev = NULL; + + for (list = conv_list; list; list = list->next) { + if (list->from_lcd == from_lcd && list->to_lcd == to_lcd + && list->from_type == from_type && list->to_type == to_type) { + + if (prev && prev != conv_list) { /* XXX */ + prev->next = list->next; + list->next = conv_list; + conv_list = list; + } + + return (*list->converter)(from_lcd, list->from, to_lcd, list->to); + } + + prev = list; + } + + return (XlcConv) NULL; +} + +Bool +_XlcSetConverter(from_lcd, from, to_lcd, to, converter) + XLCd from_lcd; + char *from; + XLCd to_lcd; + char *to; + XlcOpenConverterProc converter; +{ + register XlcConverterList list; + register XrmQuark from_type, to_type; + + from_type = XrmStringToQuark(from); + to_type = XrmStringToQuark(to); + + for (list = conv_list; list; list = list->next) { + if (list->from_lcd == from_lcd && list->to_lcd == to_lcd + && list->from_type == from_type && list->to_type == to_type) { + + list->converter = converter; + return True; + } + } + + list = (XlcConverterList) Xmalloc(sizeof(XlcConverterListRec)); + if (list == NULL) + return False; + + list->from_lcd = from_lcd; + list->from = from; + list->from_type = from_type; + list->to_lcd = to_lcd; + list->to = to; + list->to_type = to_type; + list->converter = converter; + list->next = conv_list; + conv_list = list; + + return True; +} + +typedef struct _ConvRec { + XlcConv from_conv; + XlcConv to_conv; +} ConvRec, *Conv; + +static int +indirect_convert(lc_conv, from, from_left, to, to_left, args, num_args) + XlcConv lc_conv; + XPointer *from; + int *from_left; + XPointer *to; + int *to_left; + XPointer *args; + int num_args; +{ + Conv conv = (Conv) lc_conv->state; + XlcConv from_conv = conv->from_conv; + XlcConv to_conv = conv->to_conv; + XlcCharSet charset; + char buf[BUFSIZ], *cs; + XPointer tmp_args[1]; + int cs_left, ret, length, unconv_num = 0; + + if (from == NULL || *from == NULL) { + if (from_conv->methods->reset) + (*from_conv->methods->reset)(from_conv); + + if (to_conv->methods->reset) + (*to_conv->methods->reset)(to_conv); + + return 0; + } + + while (*from_left > 0) { + cs = buf; + cs_left = BUFSIZ; + tmp_args[0] = (XPointer) &charset; + + ret = (*from_conv->methods->convert)(from_conv, from, from_left, &cs, + &cs_left, tmp_args, 1); + if (ret < 0) + break; + + length = cs_left = cs - buf; + cs = buf; + + tmp_args[0] = (XPointer) charset; + + ret = (*to_conv->methods->convert)(to_conv, &cs, &cs_left, to, to_left, + tmp_args, 1); + if (ret < 0) { + unconv_num += length / charset->char_size; + continue; + } + + if (*to_left < 1) + break; + } + + return unconv_num; +} + +static void +close_indirect_converter(lc_conv) + XlcConv lc_conv; +{ + Conv conv = (Conv) lc_conv->state; + + if (conv) { + if (conv->from_conv) + close_converter(conv->from_conv); + if (conv->to_conv) + close_converter(conv->to_conv); + + Xfree((char *) conv); + } + + Xfree((char *) lc_conv); +} + +static void +reset_indirect_converter(lc_conv) + XlcConv lc_conv; +{ + Conv conv = (Conv) lc_conv->state; + + if (conv) { + if (conv->from_conv && conv->from_conv->methods->reset) + (*conv->from_conv->methods->reset)(conv->from_conv); + if (conv->to_conv && conv->to_conv->methods->reset) + (*conv->to_conv->methods->reset)(conv->to_conv); + } +} + +static XlcConvMethodsRec conv_methods = { + close_indirect_converter, + indirect_convert, + reset_indirect_converter +} ; + +static XlcConv +open_indirect_converter(from_lcd, from, to_lcd, to) + XLCd from_lcd; + char *from; + XLCd to_lcd; + char *to; +{ + XlcConv lc_conv, from_conv, to_conv; + Conv conv; + XrmQuark from_type, to_type; + static XrmQuark QChar, QCharSet, QCTCharSet = (XrmQuark) 0; + + if (QCTCharSet == (XrmQuark) 0) { + QCTCharSet = XrmStringToQuark(XlcNCTCharSet); + QCharSet = XrmStringToQuark(XlcNCharSet); + QChar = XrmStringToQuark(XlcNChar); + } + + from_type = XrmStringToQuark(from); + to_type = XrmStringToQuark(to); + + if (from_type == QCharSet || from_type == QChar || to_type == QCharSet || + to_type == QChar) + return (XlcConv) NULL; + + lc_conv = (XlcConv) Xmalloc(sizeof(XlcConvRec)); + if (lc_conv == NULL) + return (XlcConv) NULL; + + lc_conv->methods = &conv_methods; + + lc_conv->state = (XPointer) Xcalloc(1, sizeof(ConvRec)); + if (lc_conv->state == NULL) + goto err; + + conv = (Conv) lc_conv->state; + + from_conv = get_converter(from_lcd, from_type, from_lcd, QCTCharSet); + if (from_conv == NULL) + from_conv = get_converter(from_lcd, from_type, from_lcd, QCharSet); + if (from_conv == NULL) + from_conv = get_converter((XLCd)NULL, from_type, (XLCd)NULL, QCharSet); + if (from_conv == NULL) + from_conv = get_converter(from_lcd, from_type, from_lcd, QChar); + if (from_conv == NULL) + goto err; + conv->from_conv = from_conv; + + to_conv = get_converter(to_lcd, QCTCharSet, to_lcd, to_type); + if (to_conv == NULL) + to_conv = get_converter(to_lcd, QCharSet, to_lcd, to_type); + if (to_conv == NULL) + to_conv = get_converter((XLCd) NULL, QCharSet, (XLCd) NULL, to_type); + if (to_conv == NULL) + goto err; + conv->to_conv = to_conv; + + return lc_conv; + +err: + close_indirect_converter(lc_conv); + + return (XlcConv) NULL; +} + +XlcConv +_XlcOpenConverter(from_lcd, from, to_lcd, to) + XLCd from_lcd; + char *from; + XLCd to_lcd; + char *to; +{ + XlcConv conv; + XrmQuark from_type, to_type; + + from_type = XrmStringToQuark(from); + to_type = XrmStringToQuark(to); + + if ((conv = get_converter(from_lcd, from_type, to_lcd, to_type))) + return conv; + + return open_indirect_converter(from_lcd, from, to_lcd, to); +} + +void +_XlcCloseConverter(conv) + XlcConv conv; +{ + close_converter(conv); +} + +int +_XlcConvert(conv, from, from_left, to, to_left, args, num_args) + XlcConv conv; + XPointer *from; + int *from_left; + XPointer *to; + int *to_left; + XPointer *args; + int num_args; +{ + return (*conv->methods->convert)(conv, from, from_left, to, to_left, args, + num_args); +} + +void +_XlcResetConverter(conv) + XlcConv conv; +{ + if (conv->methods->reset) + (*conv->methods->reset)(conv); +} diff --git a/src/xlibi18n/lcDB.c b/src/xlibi18n/lcDB.c new file mode 100644 index 00000000..a6d8648b --- /dev/null +++ b/src/xlibi18n/lcDB.c @@ -0,0 +1,1281 @@ +/* $Xorg: lcDB.c,v 1.6 2000/08/17 19:45:17 cpqbld Exp $ */ +/* + * + * Copyright IBM Corporation 1993 + * + * All Rights Reserved + * + * License 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 IBM not be + * used in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * + * IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING + * ALL IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS, AND + * NONINFRINGEMENT OF THIRD PARTY RIGHTS, IN NO EVENT SHALL + * IBM 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. + * +*/ +/* + * (c) Copyright 1995 FUJITSU LIMITED + * This is source code modified by FUJITSU LIMITED under the Joint + * Development Agreement for the CDE/Motif PST. + */ +#ifndef NOT_X_ENV + +#include <X11/Xlib.h> +#include <X11/Xresource.h> +#include "Xlibint.h" +#include "XlcPubI.h" + +#else /* NOT_X_ENV */ + +#define Xmalloc malloc +#define Xrealloc realloc +#define Xfree free + +#endif /* NOT_X_ENV */ + +/* specifying NOT_X_ENV allows users to just use + the database parsing routine. */ +/* For UDC/VW */ +#ifndef BUFSIZE +#define BUFSIZE 2048 +#endif + +#ifdef COMMENT +#ifdef BUFSIZE +#undef BUFSIZE +#endif +#define BUFSIZE 6144 /* 2048*3 */ +#endif + +#include <stdio.h> + +typedef struct _DatabaseRec { + char *category; + char *name; + char **value; + int value_num; + struct _DatabaseRec *next; +} DatabaseRec, *Database; + +typedef enum { + S_NULL, /* outside category */ + S_CATEGORY, /* inside category */ + S_NAME, /* has name, expecting values */ + S_VALUE +} ParseState; + +typedef enum { + T_NEWLINE, + T_COMMENT, + T_SEMICOLON, + T_DOUBLE_QUOTE, + T_LEFT_BRACE, + T_RIGHT_BRACE, + T_SPACE, + T_TAB, + T_BACKSLASH, + T_NUMERIC_HEX, + T_NUMERIC_DEC, + T_NUMERIC_OCT, + T_DEFAULT +} Token; + +typedef struct { + Token token; /* token id */ + char *name; /* token sequence */ + int len; /* length of token sequence */ + int (*parse_proc)(); /* parsing procedure */ +} TokenTable; + +static int f_newline(); +static int f_comment(); +static int f_semicolon(); +static int f_double_quote(); +static int f_left_brace(); +static int f_right_brace(); +static int f_white(); +static int f_backslash(); +static int f_numeric(); +static int f_default(); + +static TokenTable token_tbl[] = { + { T_NEWLINE, "\n", 1, f_newline }, + { T_COMMENT, "#", 1, f_comment }, + { T_SEMICOLON, ";", 1, f_semicolon }, + { T_DOUBLE_QUOTE, "\"", 1, f_double_quote }, + { T_LEFT_BRACE, "{", 1, f_left_brace }, + { T_RIGHT_BRACE, "}", 1, f_right_brace }, + { T_SPACE, " ", 1, f_white }, + { T_TAB, "\t", 1, f_white }, + { T_BACKSLASH, "\\", 1, f_backslash }, + { T_NUMERIC_HEX, "\\x", 2, f_numeric }, + { T_NUMERIC_DEC, "\\d", 2, f_numeric }, + { T_NUMERIC_OCT, "\\o", 2, f_numeric }, + { T_DEFAULT, " ", 1, f_default }, /* any character */ + 0 +}; + +#define SYM_NEWLINE '\n' +#define SYM_COMMENT '#' +#define SYM_SEMICOLON ';' +#define SYM_DOUBLE_QUOTE '"' +#define SYM_LEFT_BRACE '{' +#define SYM_RIGHT_BRACE '}' +#define SYM_SPACE ' ' +#define SYM_TAB '\t' +#define SYM_BACKSLASH '\\' + +/************************************************************************/ + +#define MAX_NAME_NEST 64 + +typedef struct { + ParseState pre_state; + char *category; + char *name[MAX_NAME_NEST]; + int nest_depth; + char **value; + int value_len; + int value_num; + int bufsize; /* bufMaxSize >= bufsize >= 0 */ + int bufMaxSize; /* default : BUFSIZE */ + char *buf; +} DBParseInfo; + +static DBParseInfo parse_info; + +static void init_parse_info() +{ + static int first = 1; + char *ptr; + int size; + if(first == 1){ + bzero(&parse_info, sizeof(DBParseInfo)); + parse_info.buf = (char *)Xmalloc(BUFSIZE); + parse_info.bufMaxSize = BUFSIZE; + first = 0; + return ; + } + ptr = parse_info.buf; + size = parse_info.bufMaxSize; + bzero(&parse_info, sizeof(DBParseInfo)); + parse_info.buf = ptr; + parse_info.bufMaxSize = size; +} + +static void +clear_parse_info() +{ + int i; + char *ptr; + int size; + parse_info.pre_state = S_NULL; + if(parse_info.category != NULL){ + Xfree(parse_info.category); + } + for(i = 0; i <= parse_info.nest_depth; ++i){ + if(parse_info.name[i]){ + Xfree(parse_info.name[i]); + } + } + if(parse_info.value){ + if(*parse_info.value){ + Xfree(*parse_info.value); + } + Xfree((char *)parse_info.value); + } + ptr = parse_info.buf; + size = parse_info.bufMaxSize; + bzero(&parse_info, sizeof(DBParseInfo)); + parse_info.buf = ptr; + parse_info.bufMaxSize = size; +} + +static Bool +realloc_parse_info(len) +int len; +{ + char *p; + + + parse_info.bufMaxSize = BUFSIZE * + ((parse_info.bufsize + len)/BUFSIZE + 1); + p = (char *)Xrealloc(parse_info.buf, parse_info.bufMaxSize); + if(p == NULL){ + return(False); + } + parse_info.buf = p; + + return(True); +} +/************************************************************************/ +typedef struct _Line { + char *str; + int cursize; + int maxsize; + int seq; +} Line; + +static void +free_line(line) + Line *line; +{ + if(line->str != NULL){ + Xfree(line->str); + } + bzero(line, sizeof(Line)); +} + +static int +realloc_line(line, size) + Line *line; + int size; +{ + char *str = line->str; + + if(str != NULL){ + str = (char *)Xrealloc(str, size); + }else{ + str = (char *)Xmalloc(size); + } + if(str == NULL){ + /* malloc error */ + if (line->str != NULL) { + Xfree(line->str); + } + bzero(line, sizeof(Line)); + return 0; + } + line->str = str; + line->maxsize = size; + return 1; +} + +#define iswhite(ch) ((ch) == SYM_SPACE || (ch) == SYM_TAB) + +static void +zap_comment(str, quoted) + char *str; + int *quoted; +{ + char *p = str; +#ifdef never + *quoted = 0; + if(*p == SYM_COMMENT){ + int len = strlen(str); + if(p[len - 1] == SYM_NEWLINE){ + *p++ = SYM_NEWLINE; + } + *p = '\0'; + } +#else + while(*p){ + if(*p == SYM_DOUBLE_QUOTE){ + if(p == str || p[-1] != SYM_BACKSLASH){ + /* unescaped double quote changes quoted state. */ + *quoted = *quoted ? 0 : 1; + } + } + if(*p == SYM_COMMENT && !*quoted){ + int pos = p - str; + if(pos == 0 || + iswhite(p[-1]) && (pos == 1 || p[-2] != SYM_BACKSLASH)){ + int len = strlen(p); + if(len > 0 && p[len - 1] == SYM_NEWLINE){ + /* newline is the identifier for finding end of value. + therefore, it should not be removed. */ + *p++ = SYM_NEWLINE; + } + *p = '\0'; + break; + } + } + ++p; + } +#endif +} + +static int +read_line(fd, line) + FILE *fd; + Line *line; +{ + char buf[BUFSIZE], *p; + int len; + int quoted = 0; /* quoted by double quote? */ + char *str; + int cur; + + str = line->str; + cur = line->cursize = 0; + + while((p = fgets(buf, BUFSIZE, fd)) != NULL){ + ++line->seq; + zap_comment(p, "ed); /* remove comment line */ + len = strlen(p); + if(len == 0){ + if(cur > 0){ + break; + } + continue; + } + if(cur + len + 1 > line->maxsize){ + /* need to reallocate buffer. */ + if(! realloc_line(line, line->maxsize + BUFSIZE)){ + return -1; /* realloc error. */ + } + str = line->str; + } + strncpy(str + cur, p, len); + + cur += len; + str[cur] = '\0'; + if(!quoted){ + if(cur > 1 && str[cur - 2] == SYM_BACKSLASH && + str[cur - 1] == SYM_NEWLINE){ + /* the line is ended backslash followed by newline. + need to concatinate the next line. */ + cur -= 2; + str[cur] = '\0'; + }else{ + break; + } + } + } + if(quoted){ + /* error. still in quoted state. */ + return -1; + } + return line->cursize = cur; +} + +/************************************************************************/ + +static Token +get_token(str) + char *str; +{ + switch(*str){ + case SYM_NEWLINE: return T_NEWLINE; + case SYM_COMMENT: return T_COMMENT; + case SYM_SEMICOLON: return T_SEMICOLON; + case SYM_DOUBLE_QUOTE: return T_DOUBLE_QUOTE; + case SYM_LEFT_BRACE: return T_LEFT_BRACE; + case SYM_RIGHT_BRACE: return T_RIGHT_BRACE; + case SYM_SPACE: return T_SPACE; + case SYM_TAB: return T_TAB; + case SYM_BACKSLASH: + switch(str[1]){ + case 'x': return T_NUMERIC_HEX; + case 'd': return T_NUMERIC_DEC; + case 'o': return T_NUMERIC_OCT; + } + return T_BACKSLASH; + default: + return T_DEFAULT; + } +} + +static int +get_word(str, word) + char *str; + char *word; +{ + char *p = str, *w = word; + Token token; + int token_len; + + while(*p != '\0'){ + token = get_token(p); + token_len = token_tbl[token].len; + if(token == T_BACKSLASH){ + p += token_len; + if(*p == '\0'){ + break; + } + token = get_token(p); + token_len = token_tbl[token].len; + }else if(token != T_COMMENT && + token != T_DEFAULT){ + break; + } + strncpy(w, p, token_len); + p += token_len; w += token_len; + } + *w = '\0'; + return p - str; /* return number of scanned chars */ +} + +static int +get_quoted_word(str, word) + char *str; + char *word; +{ + char *p = str, *w = word; + Token token; + int token_len; + + if(*p == SYM_DOUBLE_QUOTE){ + ++p; + } + while(*p != '\0'){ + token = get_token(p); + token_len = token_tbl[token].len; + if(token == T_DOUBLE_QUOTE){ + p += token_len; + goto found; + } + if(token == T_BACKSLASH){ + p += token_len; + if(*p == '\0'){ + break; + } + token = get_token(p); + token_len = token_tbl[token].len; + } + strncpy(w, p, token_len); + p += token_len; w += token_len; + } + /* error. cannot detect next double quote */ + return 0; + + found:; + *w = '\0'; + return p - str; +} + +/************************************************************************/ + +static int +append_value_list() +{ + char **value_list = parse_info.value; + char *value; + int value_num = parse_info.value_num; + int value_len = parse_info.value_len; + char *str = parse_info.buf; + int len = parse_info.bufsize; + char *p; + + if(len < 1){ + return 1; /* return with no error */ + } + + if(value_list == (char **)NULL){ + value_list = (char **)Xmalloc(sizeof(char *) * 2); + *value_list = NULL; + }else{ + char **prev_list = value_list; + + value_list = (char **) + Xrealloc(value_list, sizeof(char *) * (value_num + 2)); + if (value_list == NULL){ + Xfree(prev_list); + } + } + if(value_list == (char **)NULL){ + goto err; + } + + value = *value_list; + if(value == NULL){ + value = (char *)Xmalloc(value_len + len + 1); + }else{ + char *prev_value = value; + + value = (char *)Xrealloc(value, value_len + len + 1); + if (value == NULL){ + Xfree(prev_value); + } + } + if(value == NULL){ + goto err; + } + if(value != *value_list){ + int delta, i; + delta = value - *value_list; + *value_list = value; + for(i = 1; i < value_num; ++i){ + value_list[i] += delta; + } + } + + value_list[value_num] = p = &value[value_len]; + value_list[value_num + 1] = NULL; + strncpy(p, str, len); + p[len] = 0; + + parse_info.value = value_list; + parse_info.value_num = value_num + 1; + parse_info.value_len = value_len + len + 1; + parse_info.bufsize = 0; + return 1; + + err: + if(value_list){ + Xfree((char **)value_list); + } + if(value){ + Xfree(value); + } + parse_info.value = (char **)NULL; + parse_info.value_num = 0; + parse_info.value_len = 0; + parse_info.bufsize = 0; + return 0; +} + +static int +construct_name(name, size) + char *name; + int size; +{ + register int i, len = 0; + char *p = name; + + for(i = 0; i <= parse_info.nest_depth; ++i){ + len += strlen(parse_info.name[i]) + 1; + } + if (len >= size) + return 0; + + strcpy(p, parse_info.name[0]); + p += strlen(parse_info.name[0]); + for(i = 1; i <= parse_info.nest_depth; ++i){ + *p++ = '.'; + strcpy(p, parse_info.name[i]); + p += strlen(parse_info.name[i]); + } + return *name != '\0'; +} + +static int +store_to_database(db) + Database *db; +{ + Database new = (Database)NULL; + char name[BUFSIZE]; + + if(parse_info.pre_state == S_VALUE){ + if(! append_value_list()){ + goto err; + } + } + + if(parse_info.name[parse_info.nest_depth] == NULL){ + goto err; + } + + new = (Database)Xmalloc(sizeof(DatabaseRec)); + if(new == (Database)NULL){ + goto err; + } + bzero(new, sizeof(DatabaseRec)); + + new->category = (char *)Xmalloc(strlen(parse_info.category) + 1); + if(new->category == NULL){ + goto err; + } + strcpy(new->category, parse_info.category); + + if(! construct_name(name, sizeof(name))){ + goto err; + } + new->name = (char *)Xmalloc(strlen(name) + 1); + if(new->name == NULL){ + goto err; + } + strcpy(new->name, name); + new->next = *db; + new->value = parse_info.value; + new->value_num = parse_info.value_num; + *db = new; + + Xfree(parse_info.name[parse_info.nest_depth]); + parse_info.name[parse_info.nest_depth] = NULL; + + parse_info.value = (char **)NULL; + parse_info.value_num = 0; + parse_info.value_len = 0; + + return 1; + + err: + if(new){ + if(new->category){ + Xfree(new->category); + } + if(new->name){ + Xfree(new->name); + } + } + if(parse_info.value){ + if(*parse_info.value){ + Xfree(*parse_info.value); + } + Xfree((char **)parse_info.value); + parse_info.value = (char **)NULL; + parse_info.value_num = 0; + parse_info.value_len = 0; + } + return 0; +} + +#define END_MARK "END" +#define END_MARK_LEN 3 /*strlen(END_MARK)*/ + +static int +check_category_end(str) + char *str; +{ + char *p; + int len; + + p = str; + if(strncmp(p, END_MARK, END_MARK_LEN)){ + return 0; + } + p += END_MARK_LEN; + + while(iswhite(*p)){ + ++p; + } + len = strlen(parse_info.category); + if(strncmp(p, parse_info.category, len)){ + return 0; + } + p += len; + return p - str; +} + +/************************************************************************/ + +static int +f_newline(str, token, db) + char *str; + Token token; + Database *db; +{ + switch(parse_info.pre_state){ + case S_NULL: + case S_CATEGORY: + break; + case S_NAME: + return 0; /* no value */ + case S_VALUE: + if(!store_to_database(db)) + return 0; + parse_info.pre_state = S_CATEGORY; + break; + default: + return 0; + } + return token_tbl[token].len; +} + +static int +f_comment(str, token, db) + char *str; + Token token; + Database *db; +{ + /* NOTE: comment is already handled in read_line(), + so this function is not necessary. */ + + char *p = str; + + while(*p != SYM_NEWLINE && *p != '\0'){ + ++p; /* zap to the end of line */ + } + return p - str; +} + +static int +f_white(str, token, db) + char *str; + Token token; + Database *db; +{ + char *p = str; + + while(iswhite(*p)){ + ++p; + } + return p - str; +} + +static int +f_semicolon(str, token, db) + char *str; + Token token; + Database *db; +{ + switch(parse_info.pre_state){ + case S_NULL: + case S_CATEGORY: + case S_NAME: + return 0; + case S_VALUE: + if(! append_value_list()) + return 0; + parse_info.pre_state = S_VALUE; + break; + default: + return 0; + } + return token_tbl[token].len; +} + +static int +f_left_brace(str, token, db) + char *str; + Token token; + Database *db; +{ + switch(parse_info.pre_state){ + case S_NULL: + case S_CATEGORY: + case S_VALUE: + return 0; + case S_NAME: + if(parse_info.name[parse_info.nest_depth] == NULL || + parse_info.nest_depth + 1 > MAX_NAME_NEST) + return 0; + ++parse_info.nest_depth; + parse_info.pre_state = S_CATEGORY; + break; + default: + return 0; + } + return token_tbl[token].len; +} + +static int +f_right_brace(str, token, db) + char *str; + Token token; + Database *db; +{ + if(parse_info.nest_depth < 1) + return 0; + + switch(parse_info.pre_state){ + case S_NULL: + case S_NAME: + return 0; + case S_VALUE: + if(! store_to_database(db)) + return 0; + /* fall into next case */ + case S_CATEGORY: + if(parse_info.name[parse_info.nest_depth] != NULL){ + Xfree(parse_info.name[parse_info.nest_depth]); + parse_info.name[parse_info.nest_depth] = NULL; + } + --parse_info.nest_depth; + parse_info.pre_state = S_CATEGORY; + break; + default: + return 0; + } + return token_tbl[token].len; +} + +static int +f_double_quote(str, token, db) + char *str; + Token token; + Database *db; +{ + char word[BUFSIZE]; + char* wordp; + int len; + + if ((len = strlen (str)) < sizeof word) + wordp = word; + else + wordp = Xmalloc (len + 1); + if (wordp == NULL) + return 0; + + len = 0; + switch(parse_info.pre_state){ + case S_NULL: + case S_CATEGORY: + goto err; + case S_NAME: + case S_VALUE: + len = get_quoted_word(str, wordp); + if(len < 1) + goto err; + if( (parse_info.bufsize + (int)strlen(wordp) +1) + >= parse_info.bufMaxSize){ + if(realloc_parse_info(strlen(wordp) +1) == False){ + goto err; + } + } + strcpy(&parse_info.buf[parse_info.bufsize], wordp); + parse_info.bufsize += strlen(wordp); + parse_info.pre_state = S_VALUE; + break; + default: + goto err; + } + if (wordp != word) Xfree (wordp); + return len; /* including length of token */ + +err: + if (wordp != word) Xfree (wordp); + return 0; +} + +static int +f_backslash(str, token, db) + char *str; + Token token; + Database *db; +{ + return f_default(str, token, db); +} + +static int +f_numeric(str, token, db) + char *str; + Token token; + Database *db; +{ + char word[BUFSIZE], *p; + char* wordp; + int len; + int token_len; + + if ((len = strlen (str)) < sizeof word) + wordp = word; + else + wordp = Xmalloc (len + 1); + if (wordp == NULL) + return 0; + + switch(parse_info.pre_state){ + case S_NULL: + case S_CATEGORY: + goto err; + case S_NAME: + case S_VALUE: + token_len = token_tbl[token].len; + p = str + token_len; + len = get_word(p, wordp); + if(len < 1) + goto err; + if( (parse_info.bufsize + token_len + (int)strlen(wordp) +1) + >= parse_info.bufMaxSize){ + if(realloc_parse_info(token_len + strlen(wordp) +1) == False) + goto err; + } + strncpy(&parse_info.buf[parse_info.bufsize], str, token_len); + strcpy(&parse_info.buf[parse_info.bufsize + token_len], wordp); + parse_info.bufsize += token_len + strlen(wordp); + parse_info.pre_state = S_VALUE; + break; + default: + goto err; + } + if (wordp != word) Xfree (wordp); + return len + token_len; + +err: + if (wordp != word) Xfree (wordp); + return 0; +} + +static int +f_default(str, token, db) + char *str; + Token token; + Database *db; +{ + char word[BUFSIZE], *p; + char* wordp; + int len; + + if ((len = strlen (str)) < sizeof word) + wordp = word; + else + wordp = Xmalloc (len + 1); + if (wordp == NULL) + return 0; + + len = get_word(str, wordp); + if(len < 1) + goto err; + + switch(parse_info.pre_state){ + case S_NULL: + if(parse_info.category != NULL) + goto err; + p = (char *)Xmalloc(strlen(wordp) + 1); + if(p == NULL) + goto err; + strcpy(p, wordp); + parse_info.category = p; + parse_info.pre_state = S_CATEGORY; + break; + case S_CATEGORY: + if(parse_info.nest_depth == 0){ + if(check_category_end(str)){ + /* end of category is detected. + clear context and zap to end of this line */ + clear_parse_info(); + len = strlen(str); + break; + } + } + p = (char *)Xmalloc(strlen(wordp) + 1); + if(p == NULL) + goto err; + strcpy(p, wordp); + if(parse_info.name[parse_info.nest_depth] != NULL){ + Xfree(parse_info.name[parse_info.nest_depth]); + } + parse_info.name[parse_info.nest_depth] = p; + parse_info.pre_state = S_NAME; + break; + case S_NAME: + case S_VALUE: + if( (parse_info.bufsize + (int)strlen(wordp) +1 ) + >= parse_info.bufMaxSize){ + if(realloc_parse_info(strlen(wordp) +1) == False) + goto err; + } + strcpy(&parse_info.buf[parse_info.bufsize], wordp); + parse_info.bufsize += strlen(wordp); + parse_info.pre_state = S_VALUE; + break; + default: + goto err; + } + if (wordp != word) Xfree (wordp); + return len; + +err: + if (wordp != word) Xfree (wordp); + return 0; +} + +/************************************************************************/ + +#ifdef DEBUG +static void +PrintDatabase(db) + Database db; +{ + Database p = db; + int i = 0, j; + + printf("***\n*** BEGIN Database\n***\n"); + while(p){ + printf("%3d: ", i++); + printf("%s, %s, ", p->category, p->name); + printf("\t[%d: ", p->value_num); + for(j = 0; j < p->value_num; ++j){ + printf("%s, ", p->value[j]); + } + printf("]\n"); + p = p->next; + } + printf("***\n*** END Database\n***\n"); +} +#endif + +static void +DestroyDatabase(db) + Database db; +{ + Database p = db; + + while(p){ + if(p->category != NULL){ + Xfree(p->category); + } + if(p->name != NULL){ + Xfree(p->name); + } + if(p->value != (char **)NULL){ + if(*p->value != NULL){ + Xfree(*p->value); + } + Xfree((char *)p->value); + } + db = p->next; + Xfree((char *)p); + p = db; + } +} + +static int +CountDatabase(db) + Database db; +{ + Database p = db; + int cnt = 0; + + while(p){ + ++cnt; + p = p->next; + } + return cnt; +} + +static Database +CreateDatabase(dbfile) + char *dbfile; +{ + Database db = (Database)NULL; + FILE *fd; + Line line; + char *p; + Token token; + int len; + int error = 0; + + fd = _XFopenFile(dbfile, "r"); + if(fd == (FILE *)NULL){ + return NULL; + } + + bzero(&line, sizeof(Line)); + init_parse_info(); + + do { + int rc = read_line(fd, &line); + if(rc < 0){ + error = 1; + break; + }else if(rc == 0){ + break; + } + p = line.str; + while(*p){ + token = get_token(p); + len = (*token_tbl[token].parse_proc)(p, token, &db); + if(len < 1){ + error = 1; + break; + } + p += len; + } + } while (!error); + + if(parse_info.pre_state != S_NULL){ + clear_parse_info(); + error = 1; + } + if(error){ +#ifdef DEBUG + fprintf(stderr, "database format error at line %d.\n", line.seq); +#endif + DestroyDatabase(db); + db = (Database)NULL; + } + + fclose(fd); + free_line(&line); + +#ifdef DEBUG + PrintDatabase(db); +#endif + + return db; +} + +/************************************************************************/ + +#ifndef NOT_X_ENV + +/* locale framework functions */ + +typedef struct _XlcDatabaseRec { + XrmQuark category_q; + XrmQuark name_q; + Database db; + struct _XlcDatabaseRec *next; +} XlcDatabaseRec, *XlcDatabase; + +typedef struct _XlcDatabaseListRec { + XrmQuark name_q; + XlcDatabase lc_db; + Database database; + int ref_count; + struct _XlcDatabaseListRec *next; +} XlcDatabaseListRec, *XlcDatabaseList; + +/* database cache list (per file) */ +static XlcDatabaseList _db_list = (XlcDatabaseList)NULL; + +/************************************************************************/ +/* _XlcGetResource(lcd, category, class, value, count) */ +/*----------------------------------------------------------------------*/ +/* This function retrieves XLocale database information. */ +/************************************************************************/ +void +_XlcGetResource(lcd, category, class, value, count) + XLCd lcd; + char *category; + char *class; + char ***value; + int *count; +{ + XLCdPublicMethodsPart *methods = XLC_PUBLIC_METHODS(lcd); + + (*methods->get_resource)(lcd, category, class, value, count); + return; +} + +/************************************************************************/ +/* _XlcGetLocaleDataBase(lcd, category, class, value, count) */ +/*----------------------------------------------------------------------*/ +/* This function retrieves XLocale database information. */ +/************************************************************************/ +void +_XlcGetLocaleDataBase(lcd, category, name, value, count) + XLCd lcd; + char *category; + char *name; + char ***value; + int *count; +{ + XlcDatabase lc_db = (XlcDatabase)XLC_PUBLIC(lcd, xlocale_db); + XrmQuark category_q, name_q; + + category_q = XrmStringToQuark(category); + name_q = XrmStringToQuark(name); + for(; lc_db->db; ++lc_db){ + if(category_q == lc_db->category_q && name_q == lc_db->name_q){ + *value = lc_db->db->value; + *count = lc_db->db->value_num; + return; + } + } + *value = (char **)NULL; + *count = 0; +} + +/************************************************************************/ +/* _XlcDestroyLocaleDataBase(lcd) */ +/*----------------------------------------------------------------------*/ +/* This function destroy the XLocale Database that bound to the */ +/* specified lcd. If the XLocale Database is refered from some */ +/* other lcd, this function just decreases reference count of */ +/* the database. If no locale refers the database, this function */ +/* remove it from the cache list and free work area. */ +/************************************************************************/ +void +_XlcDestroyLocaleDataBase(lcd) + XLCd lcd; +{ + XlcDatabase lc_db = (XlcDatabase)XLC_PUBLIC(lcd, xlocale_db); + XlcDatabaseList p, prev; + + for(p = _db_list, prev = (XlcDatabaseList)NULL; p; + prev = p, p = p->next){ + if(p->lc_db == lc_db){ + if((-- p->ref_count) < 1){ + if(p->lc_db != (XlcDatabase)NULL){ + Xfree((char *)p->lc_db); + } + DestroyDatabase(p->database); + if(prev == (XlcDatabaseList)NULL){ + _db_list = p->next; + }else{ + prev->next = p->next; + } + Xfree((char*)p); + } + break; + } + } + XLC_PUBLIC(lcd, xlocale_db) = (XPointer)NULL; +} + +/************************************************************************/ +/* _XlcCreateLocaleDataBase(lcd) */ +/*----------------------------------------------------------------------*/ +/* This function create an XLocale database which correspond to */ +/* the specified XLCd. */ +/************************************************************************/ +XPointer +_XlcCreateLocaleDataBase(lcd) + XLCd lcd; +{ + XlcDatabaseList list, new; + Database p, database = (Database)NULL; + XlcDatabase lc_db = (XlcDatabase)NULL; + XrmQuark name_q; + char *name; + int i, n; + + name = _XlcFileName(lcd, "locale"); + if(name == NULL){ + return (XPointer)NULL; + } + + name_q = XrmStringToQuark(name); + for(list = _db_list; list; list = list->next){ + if(name_q == list->name_q){ + list->ref_count++; + Xfree (name); + return XLC_PUBLIC(lcd, xlocale_db) = (XPointer)list->lc_db; + } + } + + database = CreateDatabase(name); + if(database == (Database)NULL){ + Xfree (name); + return (XPointer)NULL; + } + n = CountDatabase(database); + lc_db = (XlcDatabase)Xmalloc(sizeof(XlcDatabaseRec) * (n + 1)); + if(lc_db == (XlcDatabase)NULL){ + goto err; + } + bzero(lc_db, sizeof(XlcDatabaseRec) * (n + 1)); + for(p = database, i = 0; p && i < n; p = p->next, ++i){ + lc_db[i].category_q = XrmStringToQuark(p->category); + lc_db[i].name_q = XrmStringToQuark(p->name); + lc_db[i].db = p; + } + + new = (XlcDatabaseList)Xmalloc(sizeof(XlcDatabaseListRec)); + if(new == (XlcDatabaseList)NULL){ + goto err; + } + new->name_q = name_q; + new->lc_db = lc_db; + new->database = database; + new->ref_count = 1; + new->next = _db_list; + _db_list = new; + + Xfree (name); + return XLC_PUBLIC(lcd, xlocale_db) = (XPointer)lc_db; + + err: + DestroyDatabase(database); + if(lc_db != (XlcDatabase)NULL){ + Xfree((char *)lc_db); + } + Xfree (name); + return (XPointer)NULL; +} + +#endif /* NOT_X_ENV */ diff --git a/src/xlibi18n/lcDynamic.c b/src/xlibi18n/lcDynamic.c new file mode 100644 index 00000000..64484382 --- /dev/null +++ b/src/xlibi18n/lcDynamic.c @@ -0,0 +1,74 @@ +/* $Xorg: lcDynamic.c,v 1.4 2001/02/09 02:03:39 xorgcvs Exp $ */ +/* +Copyright 1996, 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 1995 by FUJITSU LIMITED + * This is source code modified by FUJITSU LIMITED under the Joint + * Development Agreement for the CDE/Motif PST. + * + * Modifier: Takanori Tateno FUJITSU LIMITED + * + */ +#ifdef USE_DYNAMIC_LOADER +#include <stdio.h> +#include <string.h> +#include "Xlibint.h" + +#ifndef XLOCALEDIR +#define XLOCALEDIR "/usr/lib/X11/locale" +#endif + +#define LCLIBNAME "xi18n.so" + +extern void *dlopen(); +extern void *dlsym(); +extern int dlclose(); +extern char *dlerror(); + +#define LAZY 1 +#define NOW 2 +#define GLOBAL 0x100 + +XLCd +_XlcDynamicLoader(name) + char *name; +{ + char libpath[1024]; + XLCdMethods _XlcGenericMethods; + XLCd lcd; + void *nlshandler; + + sprintf(libpath,"%s/%s/%s", + XLOCALEDIR,name,LCLIBNAME); + nlshandler = dlopen(libpath,LAZY); + _XlcGenericMethods = (XLCdMethods)dlsym(nlshandler, + "genericMethods"); + lcd = _XlcCreateLC(name,_XlcGenericMethods); + + + return lcd; +} +#endif /* USE_DYNAMIC_LOADER */ diff --git a/src/xlibi18n/lcFile.c b/src/xlibi18n/lcFile.c new file mode 100644 index 00000000..164674fc --- /dev/null +++ b/src/xlibi18n/lcFile.c @@ -0,0 +1,417 @@ +/* $Xorg: lcFile.c,v 1.5 2000/12/12 12:44:05 coskrey Exp $ */ +/* + * + * Copyright IBM Corporation 1993 + * + * All Rights Reserved + * + * License 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 IBM not be + * used in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * + * IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING + * ALL IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS, AND + * NONINFRINGEMENT OF THIRD PARTY RIGHTS, IN NO EVENT SHALL + * IBM 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. + * +*/ +#include <stdio.h> +#include <ctype.h> +#include "Xlibint.h" +#include "XlcPubI.h" +#include <X11/Xos.h> +#ifdef X_NOT_STDC_ENV +extern char *getenv(); +#endif + +/************************************************************************/ + +#define iscomment(ch) ((ch) == '#' || (ch) == '\0') +#if defined(WIN32) || defined(__EMX__) /* || defined(OS2) */ +#define isreadable(f) (_XAccessFile(f)) +#else +#define isreadable(f) ((access((f), R_OK) != -1) ? 1 : 0) +#endif + +#define XLC_BUFSIZE 256 + +#ifndef X_NOT_POSIX +#ifdef _POSIX_SOURCE +#include <limits.h> +#else +#define _POSIX_SOURCE +#include <limits.h> +#undef _POSIX_SOURCE +#endif +#endif +#ifndef PATH_MAX +#ifdef WIN32 +#define PATH_MAX 512 +#else +#include <sys/param.h> +#endif +#ifndef PATH_MAX +#ifdef MAXPATHLEN +#define PATH_MAX MAXPATHLEN +#else +#define PATH_MAX 1024 +#endif +#endif +#endif + +#define NUM_LOCALEDIR 64 + +static int +parse_line(line, argv, argsize) + char *line; + char **argv; + int argsize; +{ + int argc = 0; + char *p = line; + + while(argc < argsize){ + while(isspace(*p)){ + ++p; + } + if(*p == '\0'){ + break; + } + argv[argc++] = p; + while(*p != ':' && *p != '\n' && *p != '\0'){ + ++p; + } + if(*p == '\0'){ + break; + } + *p++ = '\0'; + } + + return argc; +} + +/* parse the colon separated list in path into argv */ +int +_XlcParsePath(path, argv, argsize) + char *path; + char **argv; + int argsize; +{ + char *p = path; + int i, n; + +#if 0 + while((p = strchr(p, ':')) != NULL){ + *p = ' '; /* place space on delimter */ + } +#endif + n = parse_line(path, argv, argsize); + if(n == 0){ + return 0; + } + for(i = 0; i < n; ++i){ + int len; + p = argv[i]; + len = strlen(p); + if(p[len - 1] == '/'){ + /* eliminate slash */ + p[len - 1] = '\0'; + } + } + return n; +} + +#ifndef XLOCALEDIR +#define XLOCALEDIR "/usr/lib/X11/locale" +#endif + +static void +xlocaledir(buf, buf_len) + char *buf; + int buf_len; +{ + char *dir, *p = buf; + int len = 0; + + dir = getenv("XLOCALEDIR"); + if(dir != NULL){ + len = strlen(dir); + strncpy(p, dir, buf_len); + if (len < buf_len) { + p[len++] = ':'; + p += len; + } + } + if (len < buf_len) + strncpy(p, XLOCALEDIR, buf_len-len); + buf[buf_len-1] = '\0'; +} + +enum { LtoR, RtoL }; + +static char * +resolve_name(lc_name, file_name, direction) + char *lc_name; + char *file_name; + int direction; /* mapping direction */ +{ + FILE *fp; + char buf[XLC_BUFSIZE], *name = NULL; + + fp = _XFopenFile (file_name, "r"); + if(fp == (FILE *)NULL){ + return NULL; + } + + while(fgets(buf, XLC_BUFSIZE, fp) != NULL){ + char *p = buf; + int n; + char *args[2], *from, *to; + while(isspace(*p)){ + ++p; + } + if(iscomment(*p)){ + continue; + } + n = parse_line(p, args, 2); /* get first 2 fields */ + if(n != 2){ + continue; + } + if(direction == LtoR){ + from = args[0], to = args[1]; /* left to right */ + }else{ + from = args[1], to = args[0]; /* right to left */ + } + if(! strcmp(from, lc_name)){ + name = Xmalloc(strlen(to) + 1); + if(name != NULL){ + strcpy(name, to); + } + break; + } + } + if(fp != (FILE *)NULL){ + fclose(fp); + } + return name; +} + +/* +#define isupper(ch) ('A' <= (ch) && (ch) <= 'Z') +#define tolower(ch) ((ch) - 'A' + 'a') +*/ +static char * +lowercase(dst, src) + char *dst; + char *src; +{ + char *s, *t; + + for(s = src, t = dst; *s; ++s, ++t){ + *t = isupper(*s) ? tolower(*s) : *s; + } + *t = '\0'; + return dst; +} + +/************************************************************************/ +char * +_XlcFileName(lcd, category) + XLCd lcd; + char *category; +{ + char *siname; + char cat[XLC_BUFSIZE], dir[XLC_BUFSIZE]; + int i, n; + char *args[NUM_LOCALEDIR]; + char *file_name = NULL; + + if(lcd == (XLCd)NULL){ + return NULL; + } + + siname = XLC_PUBLIC(lcd, siname); + + lowercase(cat, category); + xlocaledir(dir,XLC_BUFSIZE); + n = _XlcParsePath(dir, args, NUM_LOCALEDIR); + for(i = 0; i < n; ++i){ + char buf[PATH_MAX], *name; + + name = NULL; + if ((5 + (args[i] ? strlen (args[i]) : 0) + + (cat ? strlen (cat) : 0)) < PATH_MAX) { + sprintf(buf, "%s/%s.dir", args[i], cat); + name = resolve_name(siname, buf, RtoL); + } + if(name == NULL){ + continue; + } + if(*name == '/'){ + /* supposed to be absolute path name */ + file_name = name; + }else{ + file_name = Xmalloc(2 + (args[i] ? strlen (args[i]) : 0) + + (name ? strlen (name) : 0)); + if (file_name != NULL) + sprintf(file_name, "%s/%s", args[i], name); + Xfree(name); + } + if(isreadable(file_name)){ + break; + } + Xfree(file_name); + file_name = NULL; + /* Then, try with next dir */ + } + return file_name; +} + +/************************************************************************/ +#ifndef LOCALE_ALIAS +#define LOCALE_ALIAS "locale.alias" +#endif + +int +_XlcResolveLocaleName(lc_name, pub) + char* lc_name; + XLCdPublicPart* pub; +{ + char dir[PATH_MAX], buf[PATH_MAX], *name = NULL; + char *dst; + int i, n, sinamelen; + char *args[NUM_LOCALEDIR]; + static char locale_alias[] = LOCALE_ALIAS; + + xlocaledir (dir, PATH_MAX); + n = _XlcParsePath(dir, args, NUM_LOCALEDIR); + for(i = 0; i < n; ++i){ + if ((2 + (args[i] ? strlen (args[i]) : 0) + + strlen (locale_alias)) < PATH_MAX) { + sprintf (buf, "%s/%s", args[i], locale_alias); + name = resolve_name (lc_name, buf, LtoR); + } + if(name != NULL){ + break; + } + } + + if (name == NULL) { + /* vendor locale name == Xlocale name, no expansion of alias */ + pub->siname = Xmalloc (strlen (lc_name) + 1); + strcpy (pub->siname, lc_name); + } else { + pub->siname = name; + } + + sinamelen = strlen (pub->siname); + if (sinamelen == 1 && pub->siname[0] == 'C') { + pub->language = pub->siname; + pub->territory = pub->codeset = NULL; + return 1; + } + + /* + * pub->siname is in the format <lang>_<terr>.<codeset>, typical would + * be "en_US.ISO8859-1", "en_US.utf8", "ru_RU.KOI-8", or ja_JP.SJIS, + * although it could be ja.SJIS too. + */ + pub->siname = Xrealloc (pub->siname, 2 * (sinamelen + 1)); + + /* language */ + dst = &pub->siname[sinamelen + 1]; + strcpy (dst, pub->siname); + pub->language = dst; + + /* territory */ + dst = strchr (dst, '_'); + if (dst) { + *dst = '\0'; + pub->territory = ++dst; + } else + dst = &pub->siname[sinamelen + 1]; + + /* codeset */ + dst = strchr (dst, '.'); + if (dst) { + *dst = '\0'; + pub->codeset = ++dst; + } + + return (pub->siname[0] != '\0') ? 1 : 0; +} + +/************************************************************************/ +int +_XlcResolveI18NPath(buf, buf_len) + char *buf; + int buf_len; +{ + if(buf != NULL){ + xlocaledir(buf, buf_len); + } + return 1; +} + +char * +_XlcLocaleDirName(dir_name, lc_name) + char *dir_name; + char *lc_name; +{ + char dir[PATH_MAX], buf[PATH_MAX], *name = NULL; + char *dst; + int i, n, sinamelen; + char *args[NUM_LOCALEDIR]; + static char locale_alias[] = LOCALE_ALIAS; + char *target_name = (char*)0; + char *target_dir = (char*)0; + + xlocaledir (dir, PATH_MAX); + n = _XlcParsePath(dir, args, 256); + for (i = 0; i < n; ++i){ + if ((2 + (args[i] ? strlen(args[i]) : 0) + + strlen(locale_alias)) < PATH_MAX) { + sprintf (buf, "%s/%s", args[i], locale_alias); + name = resolve_name(lc_name, buf, LtoR); + } + if (name != NULL){ + /* look at locale.dir */ + const char *cat = "locale"; + + target_dir = args[i]; + if (!target_dir) { + /* something wrong */ + continue; + } + if ((5 + (target_dir ? strlen (target_dir) : 0) + + (cat ? strlen(cat) : 0)) < PATH_MAX) { + sprintf(buf, "%s/%s.dir", target_dir, cat); + target_name = resolve_name(name, buf, RtoL); + } + if (target_name != NULL) { + char *p = 0; + if (p = strstr(target_name, "/XLC_LOCALE")) { + *p = '\0'; + break; + } + } + } + } + if (target_name == NULL) { + /* vendor locale name == Xlocale name, no expansion of alias */ + target_dir = args[0]; + target_name = lc_name; + } + strcpy(dir_name, target_dir); + strcat(dir_name, "/"); + strcat(dir_name, target_name); + return dir_name; +} diff --git a/src/xlibi18n/lcGeneric.c b/src/xlibi18n/lcGeneric.c new file mode 100644 index 00000000..48261139 --- /dev/null +++ b/src/xlibi18n/lcGeneric.c @@ -0,0 +1,1185 @@ +/* $Xorg: lcGeneric.c,v 1.7 2000/12/12 12:44:05 coskrey Exp $ */ +/* + * Copyright 1992, 1993 by TOSHIBA Corp. + * + * 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 TOSHIBA not be used in advertising + * or publicity pertaining to distribution of the software without specific, + * written prior permission. TOSHIBA make no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * TOSHIBA DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING + * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL + * TOSHIBA 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. + * + * Author: Katsuhisa Yano TOSHIBA Corp. + * mopi@osa.ilab.toshiba.co.jp + */ +/* + * (c) Copyright 1995 FUJITSU LIMITED + * This is source code modified by FUJITSU LIMITED under the Joint + * Development Agreement for the CDE/Motif PST. + */ + +#include <stdio.h> +#include "Xlibint.h" +#include "XlcGeneric.h" + +static XLCd create(); +static Bool initialize(); +static void destroy(); + +static XLCdPublicMethodsRec genericMethods = { + { NULL }, /* use default methods */ + { + NULL, + create, + initialize, + destroy, + NULL + } +}; + +XLCdMethods _XlcGenericMethods = (XLCdMethods) &genericMethods; + +static XLCd +create(name, methods) + char *name; + XLCdMethods methods; +{ + XLCd lcd; + XLCdPublicMethods new; + + lcd = (XLCd) Xmalloc(sizeof(XLCdRec)); + if (lcd == NULL) + return (XLCd) NULL; + bzero((char *) lcd, sizeof(XLCdRec)); + + lcd->core = (XLCdCore) Xmalloc(sizeof(XLCdGenericRec)); + if (lcd->core == NULL) + goto err; + bzero((char *) lcd->core, sizeof(XLCdGenericRec)); + + new = (XLCdPublicMethods) Xmalloc(sizeof(XLCdPublicMethodsRec)); + if (new == NULL) + goto err; + *new = *((XLCdPublicMethods) methods); + lcd->methods = (XLCdMethods) new; + + return lcd; + +err: + Xfree(lcd); + return (XLCd) NULL; +} + +static Bool +string_to_encoding(str, encoding) + char *str; + char *encoding; +{ + char *next; + long value; + int base; + + while (*str) { + if (*str == '\\') { + switch (*(str + 1)) { + case 'x': + case 'X': + base = 16; + break; + default: + base = 8; + break; + } + value = strtol(str + 2, &next, base); + if (str + 2 != next) { + *((unsigned char *) encoding++) = (unsigned char) value; + str = next; + continue; + } + } + *encoding++ = *str++; + } + + *encoding = '\0'; + + return True; +} + +static Bool +string_to_ulong(str, value) +char *str; +unsigned long *value; +{ + char *tmp1 = str; + int base; + + if(*tmp1++ != '\\'){ + tmp1--; + base = 10; + }else{ + switch(*tmp1++){ + case 'x': + base = 16; + break; + case 'o': + base = 8; + break; + case 'd': + base = 10; + break; + default: + return(False); + } + } + *value = (unsigned) strtol(tmp1, NULL, base); + return(True); +} + + +static Bool +add_charset(codeset, charset) + CodeSet codeset; + XlcCharSet charset; +{ + XlcCharSet *new_list; + int num; + + if ((num = codeset->num_charsets)) + new_list = (XlcCharSet *) Xrealloc(codeset->charset_list, + (num + 1) * sizeof(XlcCharSet)); + else + new_list = (XlcCharSet *) Xmalloc(sizeof(XlcCharSet)); + + if (new_list == NULL) + return False; + + new_list[num] = charset; + codeset->charset_list = new_list; + codeset->num_charsets = num + 1; + + return True; +} + +static CodeSet +add_codeset(gen) + XLCdGenericPart *gen; +{ + CodeSet new, *new_list; + int num; + + new = (CodeSet) Xmalloc(sizeof(CodeSetRec)); + if (new == NULL) + return NULL; + bzero((char *) new, sizeof(CodeSetRec)); + + if ((num = gen->codeset_num)) + new_list = (CodeSet *) Xrealloc(gen->codeset_list, + (num + 1) * sizeof(CodeSet)); + else + new_list = (CodeSet *) Xmalloc(sizeof(CodeSet)); + + if (new_list == NULL) + goto err; + + new_list[num] = new; + gen->codeset_list = new_list; + gen->codeset_num = num + 1; + + return new; + +err: + Xfree(new); + + return NULL; +} + +static Bool +add_parse_list(gen, type, encoding, codeset) + XLCdGenericPart *gen; + EncodingType type; + char *encoding; + CodeSet codeset; +{ + ParseInfo new, *new_list; + char *str; + unsigned char ch; + int num; + + str = (char *) Xmalloc(strlen(encoding) + 1); + if (str == NULL) + return False; + strcpy(str, encoding); + + new = (ParseInfo) Xmalloc(sizeof(ParseInfoRec)); + if (new == NULL) + goto err; + bzero((char *) new, sizeof(ParseInfoRec)); + + if (gen->mb_parse_table == NULL) { + gen->mb_parse_table = (unsigned char *) Xmalloc(256); /* 2^8 */ + if (gen->mb_parse_table == NULL) + goto err; + bzero((char *) gen->mb_parse_table, 256); + } + + if ((num = gen->mb_parse_list_num)) + new_list = (ParseInfo *) Xrealloc(gen->mb_parse_list, + (num + 2) * sizeof(ParseInfo)); + else { + new_list = (ParseInfo *) Xmalloc(2 * sizeof(ParseInfo)); + } + + if (new_list == NULL) + goto err; + + new_list[num] = new; + new_list[num + 1] = NULL; + gen->mb_parse_list = new_list; + gen->mb_parse_list_num = num + 1; + + ch = (unsigned char) *str; + if (gen->mb_parse_table[ch] == 0) + gen->mb_parse_table[ch] = num + 1; + + new->type = type; + new->encoding = str; + new->codeset = codeset; + + if (codeset->parse_info == NULL) + codeset->parse_info = new; + + return True; + +err: + Xfree(str); + if (new) + Xfree(new); + + return False; +} + +static void +free_charset(lcd) + XLCd lcd; +{ + XLCdGenericPart *gen = XLC_GENERIC_PART(lcd); + ParseInfo *parse_info; + int num; + + if (gen->mb_parse_table) + Xfree(gen->mb_parse_table); + if ((num = gen->mb_parse_list_num)) { + for (parse_info = gen->mb_parse_list; num-- > 0; parse_info++) { + if ((*parse_info)->encoding) + Xfree((*parse_info)->encoding); + Xfree(*parse_info); + } + Xfree(gen->mb_parse_list); + } + + if ((num = gen->codeset_num)) + Xfree(gen->codeset_list); +} +/* For VW/UDC */ + +#define FORWARD (unsigned long)'+' +#define BACKWARD (unsigned long)'-' + +static char *getscope(str,scp) +char *str; +FontScope scp; +{ + char* next; + unsigned long start=0,end=0,dest=0,shift=0,direction=0; + sscanf(str,"[\\x%lx,\\x%lx]->\\x%lx", &start, &end,&dest); + if( dest ){ + if(dest >= start ){ + shift = dest - start; + direction = FORWARD ; + } else { + shift = start - dest; + direction = BACKWARD; + } + } + scp->start = start ; + scp->end = end ; + scp->shift = shift ; + scp->shift_direction + = direction ; + /* .......... */ + while(*str){ + if(*str == ',' && *(str+1) == '['){ + break; + } + str++; + } + next = str+1 ; + return(next); +} + +static int count_scopemap(str) +char *str; +{ + char *ptr; + int num=0; + for(ptr=str;*ptr;ptr++){ + if(*ptr == ']'){ + num ++; + } + } + return(num); +} + +FontScope _XlcParse_scopemaps(str,size) +char *str; +int *size; +{ + int num=0,i; + FontScope scope,sc_ptr; + char *str_sc; + num = count_scopemap(str); + scope = (FontScope )Xmalloc(num * sizeof(FontScopeRec)); + if(scope == NULL) { + return (NULL); + } + for (i=0,str_sc=str,sc_ptr=scope; + i < num; i++,sc_ptr++){ + str_sc = getscope(str_sc,sc_ptr); + } + *size = num; + return (scope); +} + +void _XlcDbg_printValue(str,value,num) +char *str; +char **value; +int num; +{ +/* + int i; + for(i=0;i<num;i++){ + fprintf(stderr,"%s value[%d] = %s\n",str,i,value[i]); + } +*/ +} + +static void dmpscope(name,sc,num) +char* name; +FontScope sc; +int num; +{ +/* + int i; + fprintf(stderr,"dmpscope %s\n",name); + for(i=0;i<num;i++){ + fprintf(stderr,"%x %x %x %x \n", + sc[i].start, + sc[i].end, + sc[i].shift, + sc[i].shift_direction); + } + fprintf(stderr,"dmpscope end\n"); +*/ +} + +static XlcCharSet srch_charset_define(name,new) +char *name; +int *new; +{ + XlcCharSet charset = NULL; + *new = 0; + charset = _XlcGetCharSet(name); + if (charset == NULL && + (charset = _XlcCreateDefaultCharSet(name, ""))) { + _XlcAddCharSet(charset); + *new = 1; + } + return(charset); +} + +static void read_charset_define(lcd,gen) +XLCd lcd; +XLCdGenericPart *gen; +{ + int i=0; + char csd[16],cset_name[256]; + char name[BUFSIZ]; + XlcCharSet charsetd; + char **value; + int num,new; + XlcSide side = XlcUnknown; + char *tmp; + + for(i=0;;i++){ /* loop start */ + charsetd = 0; + sprintf(csd, "csd%d", i); + + /* charset_name */ + sprintf(name, "%s.%s", csd , "charset_name"); + _XlcGetResource(lcd, "XLC_CHARSET_DEFINE", name, &value, &num); + _XlcDbg_printValue(name,value,num); + if (num > 0) { + /* hackers will get truncated -- C'est la vie */ + strncpy(cset_name,value[0], sizeof cset_name - 1); + cset_name[(sizeof cset_name) - 1] = '\0'; + sprintf(name, "%s.%s", csd , "side"); + _XlcGetResource(lcd, "XLC_CHARSET_DEFINE", name, &value, &num); + if (num > 0) { + _XlcDbg_printValue(name,value,num); + if( !_XlcNCompareISOLatin1(value[0], "none", 4) ){ + side = XlcNONE ; + strcat(cset_name,":none"); + } else + if( !_XlcNCompareISOLatin1(value[0], "GL", 2) ){ + side = XlcGL ; + strcat(cset_name,":GL"); + } else { + side = XlcGR ; + strcat(cset_name,":GR"); + } + if (charsetd == NULL && + (charsetd = srch_charset_define(cset_name,&new)) == NULL) + return ; + } + } else { + if(i == 0){ + continue ; + } else { + break ; + } + } + if(new){ + tmp = (char *)Xmalloc(strlen(cset_name)+1); + if(tmp == NULL){ + return ; + } + strcpy(tmp,cset_name); + charsetd->name = tmp; + } + /* side */ + charsetd->side = side ; + /* length */ + sprintf(name, "%s.%s", csd , "length"); + _XlcGetResource(lcd, "XLC_CHARSET_DEFINE", name, &value, &num); + if (num > 0) { + _XlcDbg_printValue(name,value,num); + charsetd->char_size = atoi(value[0]); + } + /* gc_number */ + sprintf(name, "%s.%s", csd , "gc_number"); + _XlcGetResource(lcd, "XLC_CHARSET_DEFINE", name, &value, &num); + if (num > 0) { + _XlcDbg_printValue(name,value,num); + charsetd->set_size = atoi(value[0]); + } + /* string_encoding */ + sprintf(name, "%s.%s", csd , "string_encoding"); + _XlcGetResource(lcd, "XLC_CHARSET_DEFINE", name, &value, &num); + if (num > 0) { + _XlcDbg_printValue(name,value,num); + if(!strcmp("False",value[0])){ + charsetd->string_encoding = False; + } else { + charsetd->string_encoding = True; + } + } + /* sequence */ + sprintf(name, "%s.%s", csd , "sequence"); + _XlcGetResource(lcd, "XLC_CHARSET_DEFINE", name, &value, &num); + if (num > 0) { + _XlcDbg_printValue(name,value,num); +/* + if(charsetd->ct_sequence){ + Xfree(charsetd->ct_sequence); + } +*/ + tmp = (char *)Xmalloc(strlen(value[0])+1); + if(tmp == NULL){ + return; + } + charsetd->ct_sequence = tmp; + string_to_encoding(value[0],tmp); + } + /* encoding_name */ + sprintf(name, "%s.%s", csd , "encoding_name"); + _XlcGetResource(lcd, "XLC_CHARSET_DEFINE", name, &value, &num); + if (num > 0) { + _XlcDbg_printValue(name,value,num); +/* + if(charsetd->encoding_name){ + Xfree(charsetd->encoding_name); + } +*/ + tmp = (char *)Xmalloc(strlen(value[0]+1)); + strcpy(tmp,value[0]); + charsetd->encoding_name = tmp; + charsetd->xrm_encoding_name = + XrmStringToQuark(tmp); + } + } + +} + +SegConv +add_conversion(gen) +XLCdGenericPart *gen; +{ + SegConv new_list; + int num; + + if ((num = gen->segment_conv_num)){ + new_list = (SegConv) Xrealloc(gen->segment_conv, + (num + 1) * sizeof(SegConvRec)); + } else { + new_list = (SegConv) Xmalloc(sizeof(SegConvRec)); + } + + if (new_list == NULL) + return False; + + gen->segment_conv = new_list; + gen->segment_conv_num = num + 1; + + return (&new_list[num]); + +} +static void read_segmentconversion(lcd,gen) +XLCd lcd; +XLCdGenericPart *gen; +{ + int i=0; + char conv[16]; + char name[BUFSIZ]; + char **value; + int num,new; + SegConv conversion; + for(i=0 ; ; i++){ /* loop start */ + conversion = 0; + sprintf(conv, "conv%d", i); + + /* length */ + sprintf(name, "%s.%s", conv , "length"); + _XlcGetResource(lcd, "XLC_SEGMENTCONVERSION", name, &value, &num); + if (num > 0) { + if (conversion == NULL && + (conversion = add_conversion(gen)) == NULL) { + return ; + } + _XlcDbg_printValue(name,value,num); + } else { + if(i == 0){ + continue; + } else { + break ; + } + } + conversion->length = atoi(value[0]); + + /* source_encoding */ + sprintf(name, "%s.%s", conv , "source_encoding"); + _XlcGetResource(lcd, "XLC_SEGMENTCONVERSION", name, &value, &num); + if (num > 0) { + char *tmp; + _XlcDbg_printValue(name,value,num); + tmp = (char *)Xmalloc(strlen(value[0])+1); + if(tmp == NULL){ + return; + } + strcpy(tmp,value[0]); + conversion->source_encoding = tmp; + conversion->source = srch_charset_define(tmp,&new); + if(new){ + tmp = (char *)Xmalloc(strlen(conversion->source_encoding)+1); + if(tmp == NULL){ + return ; + } + strcpy(tmp,conversion->source_encoding); + conversion->source->name = tmp; + } + } + /* destination_encoding */ + sprintf(name, "%s.%s", conv , "destination_encoding"); + _XlcGetResource(lcd, "XLC_SEGMENTCONVERSION", name, &value, &num); + if (num > 0) { + char *tmp; + _XlcDbg_printValue(name,value,num); + tmp = (char *)Xmalloc(strlen(value[0])+1); + if(tmp == NULL){ + return; + } + strcpy(tmp,value[0]); + conversion->destination_encoding = tmp; + conversion->dest = srch_charset_define(tmp,&new); + if(new){ + tmp = (char *)Xmalloc( + strlen(conversion->destination_encoding)+1); + if(tmp == NULL){ + return ; + } + strcpy(tmp,conversion->destination_encoding); + conversion->dest->name = tmp; + } + } + /* range */ + sprintf(name, "%s.%s", conv , "range"); + _XlcGetResource(lcd, "XLC_SEGMENTCONVERSION", name, &value, &num); + if (num > 0) { + _XlcDbg_printValue(name,value,num); + sscanf(value[0],"\\x%lx,\\x%lx", + &(conversion->range.start), + &(conversion->range.end)); + } + /* conversion */ + sprintf(name, "%s.%s", conv , "conversion"); + _XlcGetResource(lcd, "XLC_SEGMENTCONVERSION", name, &value, &num); + if (num > 0) { + _XlcDbg_printValue(name,value,num); + conversion->conv = + _XlcParse_scopemaps(value[0],&conversion->conv_num); + } + } /* loop end */ +} + +static ExtdSegment create_ctextseg(value,num) +char **value; +int num; +{ + ExtdSegment ret; + char* ptr; + char* cset_name = NULL; + int i,new; + FontScope scope; + ret = (ExtdSegment)Xmalloc(sizeof(ExtdSegmentRec)); + if(ret == NULL){ + return NULL; + } + if(strchr(value[0],':')){ + ret->name = (char *)Xmalloc(strlen(value[0])+1); + if(ret->name == NULL){ + Xfree (ret); + return NULL; + } + strcpy(ret->name,value[0]); + ptr = strchr(ret->name,':'); + *ptr = '\0'; + ptr++; + cset_name = (char*) Xmalloc (strlen (ret->name) + 6); + if (cset_name == NULL) { + Xfree (ret->name); + Xfree (ret); + return NULL; + } + if( !_XlcNCompareISOLatin1(ptr, "none", 4) ){ + ret->side = XlcNONE ; + sprintf(cset_name,"%s:%s",ret->name,"none"); + } else + if( !_XlcNCompareISOLatin1(ptr, "GL", 2) ){ + ret->side = XlcGL ; + sprintf(cset_name,"%s:%s",ret->name,"GL"); + } else { + ret->side = XlcGR ; + sprintf(cset_name,"%s:%s",ret->name,"GR"); + } + } else { + ret->name = (char *)Xmalloc(strlen(value[0])+1); + if(ret->name == NULL){ + Xfree (ret); + return NULL; + } + strcpy(ret->name,value[0]); + } + ret->area = (FontScope)Xmalloc((num - 1)*sizeof(FontScopeRec)); + if(ret->area == NULL){ + Xfree (ret->name); + Xfree (ret); + return NULL; + } + ret->area_num = num - 1; + scope = ret->area ; + for(i=1;i<num;i++){ + sscanf(value[i],"\\x%lx,\\x%lx", + &scope[i-1].start,&scope[i-1].end); + } + ret->charset = srch_charset_define(cset_name,&new); + if (new) + ret->charset->name = cset_name; + else + Xfree (cset_name); + + return ret; +} +/* For VW/UDC end */ + +static Bool +load_generic(lcd) + XLCd lcd; +{ + XLCdGenericPart *gen = XLC_GENERIC_PART(lcd); + char **value; + int num; + unsigned long l; + int i; + int M,ii; + + gen->codeset_num = 0; + + /***** wc_encoding_mask *****/ + _XlcGetResource(lcd, "XLC_XLOCALE", "wc_encoding_mask", &value, &num); + if (num > 0) { + if (string_to_ulong(value[0], &l) == False) + goto err; + gen->wc_encode_mask = l; + } + /***** wc_shift_bits *****/ + _XlcGetResource(lcd, "XLC_XLOCALE", "wc_shift_bits", &value, &num); + if (num > 0) + gen->wc_shift_bits = atoi(value[0]); + if (gen->wc_shift_bits < 1) + gen->wc_shift_bits = 8; +#ifndef X_NOT_STDC_ENV + /***** use_stdc_env *****/ + _XlcGetResource(lcd, "XLC_XLOCALE", "use_stdc_env", &value, &num); + if (num > 0 && !_XlcCompareISOLatin1(value[0], "True")) + gen->use_stdc_env = True; + else + gen->use_stdc_env = False; + /***** force_convert_to_mb *****/ + _XlcGetResource(lcd, "XLC_XLOCALE", "force_convert_to_mb", &value, &num); + if (num > 0 && !_XlcCompareISOLatin1(value[0], "True")) + gen->force_convert_to_mb = True; + else + gen->force_convert_to_mb = False; +#endif + + for (i = 0; ; i++) { + CodeSetRec *codeset = NULL; + char cs[16]; + char name[BUFSIZ]; + + sprintf(cs, "cs%d", i); + + /***** codeset.side *****/ + sprintf(name, "%s.%s", cs , "side"); + _XlcGetResource(lcd, "XLC_XLOCALE", name, &value, &num); + if (num > 0) { + char *tmp; + + if (codeset == NULL && (codeset = add_codeset(gen)) == NULL) + goto err; + + /* 3.4.1 side */ + if( !_XlcNCompareISOLatin1(value[0], "none", 4) ){ + codeset->side = XlcNONE ; + } else + if( !_XlcNCompareISOLatin1(value[0], "GL", 2) ){ + codeset->side = XlcGL ; + } else { + codeset->side = XlcGR ; + } + + tmp = strrchr(value[0], ':'); + if (tmp != NULL && !_XlcCompareISOLatin1(tmp + 1, "Default")) { + if (codeset->side == XlcGR) + gen->initial_state_GR = codeset; + else + gen->initial_state_GL = codeset; + } + } + + /***** codeset.length *****/ + sprintf(name, "%s.%s", cs , "length"); + _XlcGetResource(lcd, "XLC_XLOCALE", name, &value, &num); + if (num > 0) { + if (codeset == NULL && (codeset = add_codeset(gen)) == NULL) + goto err; + codeset->length = atoi(value[0]); + if (codeset->length < 1) + codeset->length = 1; + } + + /***** codeset.mb_encoding *****/ + sprintf(name, "%s.%s", cs, "mb_encoding"); + _XlcGetResource(lcd, "XLC_XLOCALE", name, &value, &num); + if (num > 0) { + static struct { + char *str; + int type; + } shifts[] = { + {"<SS>", E_SS}, + {"<LSL>", E_LSL}, + {"<LSR>", E_LSR}, + 0 + }; + int j; + + if (codeset == NULL && (codeset = add_codeset(gen)) == NULL) + goto err; + for ( ; num-- > 0; value++) { + char encoding[256]; + char *tmp = *value; + int type = E_SS; /* for BC */ + for (j = 0; shifts[j].str; j++) { + if (!_XlcNCompareISOLatin1(tmp, shifts[j].str, + strlen(shifts[j].str))) { + type = shifts[j].type; + tmp += strlen(shifts[j].str); + break; + } + } + if (strlen (tmp) > sizeof encoding || + string_to_encoding(tmp, encoding) == False) + goto err; + add_parse_list(gen, type, encoding, codeset); + } + } + + /***** codeset.wc_encoding *****/ + sprintf(name, "%s.%s", cs, "wc_encoding"); + _XlcGetResource(lcd, "XLC_XLOCALE", name, &value, &num); + if (num > 0) { + if (codeset == NULL && (codeset = add_codeset(gen)) == NULL) + goto err; + if (string_to_ulong(value[0], &l) == False) + goto err; + codeset->wc_encoding = l; + } + + /***** codeset.ct_encoding *****/ + sprintf(name, "%s.%s", cs, "ct_encoding"); + _XlcGetResource(lcd, "XLC_XLOCALE", name, &value, &num); + if (num > 0) { + XlcCharSet charset; + char *encoding; + + if (codeset == NULL && (codeset = add_codeset(gen)) == NULL) + goto err; + for ( ; num-- > 0; value++) { + if (strlen (*value) > sizeof name) + goto err; + string_to_encoding(*value, name); + charset = NULL; + if ((encoding = strchr(name, ':')) && + (encoding = strchr(encoding + 1, ':'))) { + *encoding++ = '\0'; + charset = _XlcAddCT(name, encoding); + } + if (charset == NULL) { + charset = _XlcGetCharSet(name); + if (charset == NULL && + (charset = _XlcCreateDefaultCharSet(name, ""))) { + charset->side = codeset->side; + charset->char_size = codeset->length; + _XlcAddCharSet(charset); + } + } + if (charset) { + if (add_charset(codeset, charset) == False) + goto err; + } + } + } + + if (codeset == NULL) + break; + codeset->cs_num = i; + /* For VW/UDC */ + /***** 3.4.2 byteM (1 <= M <= length)*****/ + for(M=1; M-1 < codeset->length; M++){ + long start,end; + ByteInfo tmpb; + + sprintf(name,"%s.%s%d",cs,"byte",M); + _XlcGetResource(lcd, "XLC_XLOCALE", name, &value, &num); + + if( M == 1){ + if(num < 1) { + codeset->byteM = NULL ; + break ; + } + codeset->byteM = + (ByteInfoListRec *)Xmalloc( + (codeset->length)*sizeof(ByteInfoListRec)); + if(codeset->byteM == NULL){ + goto err; + } + } + + if(num > 0){ + _XlcDbg_printValue(name,value,num); + (codeset->byteM)[M-1].M = M; + (codeset->byteM)[M-1].byteinfo_num = num; + (codeset->byteM)[M-1].byteinfo = + (ByteInfo)Xmalloc( num * sizeof(ByteInfoRec)); + for(ii = 0 ; ii < num ; ii++){ + tmpb = (codeset->byteM)[M-1].byteinfo ; + /* default 0x00 - 0xff */ + sscanf(value[ii],"\\x%lx,\\x%lx",&start,&end); + tmpb[ii].start = (unsigned char)start; + tmpb[ii].end = (unsigned char)end; + } + } + /* .... */ + } + + + /***** codeset.mb_conversion *****/ + sprintf(name, "%s.%s", cs, "mb_conversion"); + _XlcGetResource(lcd, "XLC_XLOCALE", name, &value, &num); + if (num > 0) { + _XlcDbg_printValue(name,value,num); + codeset->mbconv = Xmalloc(sizeof(ConversionRec)); + codeset->mbconv->convlist = + _XlcParse_scopemaps(value[0],&(codeset->mbconv->conv_num)); + dmpscope("mb_conv",codeset->mbconv->convlist, + codeset->mbconv->conv_num); + /* [\x%x,\x%x]->\x%x,... */ + } + /***** codeset.ct_conversion *****/ + sprintf(name, "%s.%s", cs, "ct_conversion"); + _XlcGetResource(lcd, "XLC_XLOCALE", name, &value, &num); + if (num > 0) { + _XlcDbg_printValue(name,value,num); + codeset->ctconv = Xmalloc(sizeof(ConversionRec)); + codeset->ctconv->convlist = + _XlcParse_scopemaps(value[0],&(codeset->ctconv->conv_num)); + dmpscope("ctconv",codeset->ctconv->convlist, + codeset->ctconv->conv_num); + /* [\x%x,\x%x]->\x%x,... */ + } + /***** codeset.ct_conversion_file *****/ + sprintf(name, "%s.%s", cs, "ct_conversion_file"); + _XlcGetResource(lcd, "XLC_XLOCALE", name, &value, &num); + if (num > 0) { + _XlcDbg_printValue(name,value,num); + /* [\x%x,\x%x]->\x%x,... */ + } + /***** codeset.ct_extended_segment *****/ + sprintf(name, "%s.%s", cs, "ct_extended_segment"); + _XlcGetResource(lcd, "XLC_XLOCALE", name, &value, &num); + if (num > 0) { + _XlcDbg_printValue(name,value,num); + codeset->ctextseg = create_ctextseg(value,num); + /* [\x%x,\x%x]->\x%x,... */ + } + /* For VW/UDC end */ + + } + + read_charset_define(lcd,gen); /* For VW/UDC */ + read_segmentconversion(lcd,gen); /* For VW/UDC */ + + return True; + +err: + free_charset(lcd); + + return False; +} + +#ifdef USE_DYNAMIC_LC +/* override the open_om and open_im methods which were set by + super_class's initialize method() */ + +static Bool +initialize_core(lcd) + XLCd lcd; +{ + _XInitDynamicOM(lcd); + + _XInitDynamicIM(lcd); + + return True; +} +#endif + +static Bool +initialize(lcd) + XLCd lcd; +{ + XLCdPublicMethods superclass = (XLCdPublicMethods) _XlcPublicMethods; + + XLC_PUBLIC_METHODS(lcd)->superclass = superclass; + + if (superclass->pub.initialize) { + if ((*superclass->pub.initialize)(lcd) == False) + return False; + } + +#ifdef USE_DYNAMIC_LC + if (initialize_core(lcd) == False) + return False; +#endif + + if(load_generic(lcd) == False) + return False; + + return True; +} +/* VW/UDC start 95.01.08 */ +static void +freeByteM(codeset) + CodeSet codeset; +{ + int i; + ByteInfoList blst; + if(codeset->byteM == NULL) { + return ; + } + blst = codeset->byteM; + for(i=0;i<codeset->length;i++){ + if(blst[i].byteinfo){ + Xfree(blst[i].byteinfo); + blst[i].byteinfo = NULL; + } + } + Xfree(codeset->byteM); + codeset->byteM = NULL; +} +static void +freeConversion(codeset) + CodeSet codeset; +{ + Conversion mbconv,ctconv; + if( codeset->mbconv ) { + mbconv = codeset->mbconv; + /* ... */ + if(mbconv->convlist){ + Xfree(mbconv->convlist); + mbconv->convlist = NULL; + } + Xfree(mbconv); + codeset->mbconv = NULL; + } + if( codeset->ctconv ) { + ctconv = codeset->ctconv; + /* ... */ + if(ctconv->convlist){ + Xfree(ctconv->convlist); + ctconv->convlist = NULL; + } + Xfree(ctconv); + codeset->ctconv = NULL; + } +} +static void +freeExtdSegment(codeset) + CodeSet codeset; +{ + ExtdSegment ctextseg; + if(codeset->ctextseg == NULL) { + return ; + } + ctextseg = codeset->ctextseg; + if(ctextseg->name){ + Xfree(ctextseg->name); + ctextseg->name = NULL; + } + if(ctextseg->area){ + Xfree(ctextseg->area); + ctextseg->area = NULL; + } + Xfree(codeset->ctextseg); + codeset->ctextseg = NULL; +} +static void +freeParseInfo(codeset) + CodeSet codeset; +{ + ParseInfo parse_info; + if(codeset->parse_info == NULL) { + return ; + } + parse_info = codeset->parse_info; + if(parse_info->encoding){ + Xfree(parse_info->encoding); + parse_info->encoding = NULL; + } + Xfree(codeset->parse_info); + codeset->parse_info = NULL; +} +static void +destroy_CodeSetList(gen) + XLCdGenericPart *gen ; +{ + CodeSet *codeset = gen->codeset_list; + int i; + if(gen->codeset_num == 0) { + return; + } + for(i=0;i<gen->codeset_num;i++){ + freeByteM(codeset[i]); + freeConversion(codeset[i]); + freeExtdSegment(codeset[i]); + freeParseInfo(codeset[i]); + if(codeset[i]->charset_list){ + Xfree(codeset[i]->charset_list); + codeset[i]->charset_list = NULL; + } + Xfree(codeset[i]); codeset[i]=NULL; + } + Xfree(codeset); gen->codeset_list = NULL; +} +/* */ +static void +destroy_SegConv(gen) + XLCdGenericPart *gen ; +{ + SegConv seg = gen->segment_conv; + int i; + if(gen->segment_conv_num == 0) { + return; + } + for(i=0;i<gen->segment_conv_num;i++){ + if(seg[i].source_encoding){ + Xfree(seg[i].source_encoding); + seg[i].source_encoding = NULL; + } + if(seg[i].destination_encoding){ + Xfree(seg[i].destination_encoding); + seg[i].destination_encoding = NULL; + } + if(seg[i].conv){ + Xfree(seg[i].conv); seg[i].conv = NULL; + } + } + Xfree(seg); gen->segment_conv = NULL; +} + +static void +destroy_gen(lcd) + XLCd lcd; +{ + XLCdGenericPart *gen = XLC_GENERIC_PART(lcd); + destroy_SegConv(gen); + destroy_CodeSetList(gen); + if(gen->mb_parse_table){ + Xfree(gen->mb_parse_table); + gen->mb_parse_table = NULL; + } + if(gen->mb_parse_list){ + Xfree(gen->mb_parse_list); + gen->mb_parse_list = NULL; + } +} +/* VW/UDC end 95.01.08 */ +static void +destroy(lcd) + XLCd lcd; +{ + XLCdPublicMethods superclass = XLC_PUBLIC_METHODS(lcd)->superclass; + + destroy_gen(lcd); /* ADD 1996.01.08 */ + if (superclass && superclass->pub.destroy) + (*superclass->pub.destroy)(lcd); +} diff --git a/src/xlibi18n/lcInit.c b/src/xlibi18n/lcInit.c new file mode 100644 index 00000000..e4d3a7a4 --- /dev/null +++ b/src/xlibi18n/lcInit.c @@ -0,0 +1,229 @@ +/* +Copyright 1985, 1986, 1987, 1991, 1998 The Open Group + +Portions Copyright 2000 Sun Microsystems, Inc. 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 THE OPEN GROUP OR SUN MICROSYSTEMS, INC. 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 EVEN IF +ADVISED IN ADVANCE OF THE POSSIBILITY OF SUCH DAMAGES. + + +Except as contained in this notice, the names of The Open Group and/or +Sun Microsystems, Inc. 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 and/or Sun Microsystems, +Inc., as applicable. + + +X Window System is a trademark of The Open Group + +OSF/1, OSF/Motif and Motif are registered trademarks, and OSF, the OSF +logo, LBX, X Window System, and Xinerama are trademarks of the Open +Group. All other trademarks and registered trademarks mentioned herein +are the property of their respective owners. No right, title or +interest in or to any trademark, service mark, logo or trade name of +Sun Microsystems, Inc. or its licensors is granted. + +*/ +/* $Xorg: lcInit.c,v 1.4 2000/12/12 12:44:05 coskrey Exp $ */ +/* + * Copyright 1992, 1993 by TOSHIBA Corp. + * + * 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 TOSHIBA not be used in advertising + * or publicity pertaining to distribution of the software without specific, + * written prior permission. TOSHIBA make no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * TOSHIBA DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING + * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL + * TOSHIBA 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. + * + * Author: Katsuhisa Yano TOSHIBA Corp. + * mopi@osa.ilab.toshiba.co.jp + */ +/* + * (c) Copyright 1995 FUJITSU LIMITED + * This is source code modified by FUJITSU LIMITED under the Joint + * Development Agreement for the CDE/Motif PST. + * + * Modifier: Masayoshi Shimamura FUJITSU LIMITED + * + */ + +#include "Xlibint.h" +#include "Xlcint.h" + +#ifdef USE_DYNAMIC_LC +#undef USE_DEFAULT_LOADER +#else +#define USE_GENERIC_LOADER +#define USE_DEFAULT_LOADER +#ifdef X_LOCALE +# define USE_EUC_LOADER +# define USE_SJIS_LOADER +# define USE_JIS_LOADER +# define USE_UTF_LOADER +#endif +#endif + +#ifdef USE_DEFAULT_LOADER +extern XLCd _XlcDefaultLoader( +#if NeedFunctionPrototypes + char* +#endif +); +#endif + +#ifdef USE_DYNAMIC_LC +extern XLCd _XlcDynamicLoad( +#if NeedFunctionPrototypes + char* +#endif +); +#endif + +#ifdef DYNAMIC_LOAD +#ifdef AIXV3 +extern XLCd _XaixOsDynamicLoad( +#if NeedFunctionPrototypes + char* +#endif +); +#endif /* AIXV3 */ +#endif + +#ifdef USE_GENERIC_LOADER +extern XLCd _XlcGenericLoader( +#if NeedFunctionPrototypes + char* +#endif +); +#endif + +#ifdef USE_UTF_LOADER +extern XLCd _XlcUtfLoader( +#if NeedFunctionPrototypes + char* +#endif +); +#endif + +#ifdef USE_EUC_LOADER +extern XLCd _XlcEucLoader( +#if NeedFunctionPrototypes + char* +#endif +); +#endif + +#ifdef USE_SJIS_LOADER +extern XLCd _XlcSjisLoader( +#if NeedFunctionPrototypes + char* +#endif +); +#endif + +#ifdef USE_JIS_LOADER +extern XLCd _XlcJisLoader( +#if NeedFunctionPrototypes + char* +#endif +); +#endif + +#ifdef USE_DYNAMIC_LOADER +extern XLCd _XlcDynamicLoader( +#if NeedFunctionPrototypes + char* +#endif +); +#endif + +/* + * The _XlcInitLoader function initializes the locale object loader list + * with vendor specific manner. + */ + +void +#if NeedFunctionPrototypes +_XlcInitLoader(char *name) +#else +_XlcInitLoader(name) + char *name; +#endif +{ + +#ifdef USE_DYNAMIC_LC + _XlcAddLoader(_XlcDynamicLoad, XlcHead); + +#ifdef USE_DEFAULT_LOADER + if (strcmp(name, "C") == 0 || strcmp(name, "POSIX") == 0) + _XlcAddLoader(_XlcDefaultLoader, XlcHead); + else + _XlcAddLoader(_XlcDefaultLoader, XlcTail); +#endif + +#else /* USE_DYNAMIC_LC */ + +#ifdef USE_GENERIC_LOADER + _XlcAddLoader(_XlcGenericLoader, XlcHead); +#endif + +#ifdef USE_DEFAULT_LOADER + _XlcAddLoader(_XlcDefaultLoader, XlcHead); +#endif + +#ifdef USE_EUC_LOADER + _XlcAddLoader(_XlcEucLoader, XlcHead); +#endif + +#ifdef USE_SJIS_LOADER + _XlcAddLoader(_XlcSjisLoader, XlcHead); +#endif + +#ifdef USE_JIS_LOADER + _XlcAddLoader(_XlcJisLoader, XlcHead); +#endif + +#ifdef USE_UTF_LOADER + _XlcAddLoader(_XlcUtfLoader, XlcHead); +#endif + +#endif /* USE_DYNAMIC_LC */ + +#ifdef DYNAMIC_LOAD +#ifdef AIXV3 + _XlcAddLoader(_XaixOsDynamicLoad, XlcHead); +#endif /* AIXV3 */ +#endif /* DYNAMIC_LOAD */ + +#ifdef USE_DYNAMIC_LOADER + _XlcAddLoader(_XlcDynamicLoader, XlcHead); +#endif +} diff --git a/src/xlibi18n/lcPrTxt.c b/src/xlibi18n/lcPrTxt.c new file mode 100644 index 00000000..c06a628f --- /dev/null +++ b/src/xlibi18n/lcPrTxt.c @@ -0,0 +1,252 @@ +/* $Xorg: lcPrTxt.c,v 1.3 2000/08/17 19:45:18 cpqbld Exp $ */ +/* + * Copyright 1992, 1993 by TOSHIBA Corp. + * + * 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 TOSHIBA not be used in advertising + * or publicity pertaining to distribution of the software without specific, + * written prior permission. TOSHIBA make no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * TOSHIBA DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING + * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL + * TOSHIBA 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. + * + * Author: Katsuhisa Yano TOSHIBA Corp. + * mopi@osa.ilab.toshiba.co.jp + */ + +#include "Xlibint.h" +#include "XlcPubI.h" +#include <X11/Xutil.h> +#include <X11/Xatom.h> + +static XPointer * +alloc_list(is_wide_char, count, nitems) + Bool is_wide_char; + int count; + int nitems; +{ + if (is_wide_char) { + wchar_t **wstr_list; + + wstr_list = (wchar_t **) Xmalloc(count * sizeof(wchar_t *)); + if (wstr_list == NULL) + return (XPointer *) NULL; + + *wstr_list = (wchar_t *) Xmalloc(nitems * sizeof(wchar_t)); + if (*wstr_list == NULL) { + Xfree(wstr_list); + return (XPointer *) NULL; + } + + return (XPointer *) wstr_list; + } else { + char **str_list; + + str_list = (char **) Xmalloc(count * sizeof(char *)); + if (str_list == NULL) + return (XPointer *) NULL; + + *str_list = (char *) Xmalloc(nitems); + if (*str_list == NULL) { + Xfree(str_list); + return (XPointer *) NULL; + } + + return (XPointer *) str_list; + } +} + +static void +copy_list(is_wide_char, text, list, count) + Bool is_wide_char; + XPointer text; + XPointer *list; + int count; +{ + int length; + + if (is_wide_char) { + wchar_t *wc_text, *wstr, **wstr_list; + + wc_text = (wchar_t *) text; + wstr_list = (wchar_t **) list; + + for (wstr = *wstr_list; count > 0; count--, wstr_list++) { + _Xwcscpy(wstr, wc_text); + *wstr_list = wstr; + length = _Xwcslen(wstr) + 1; + wstr += length; + wc_text += length; + } + } else { + char *mb_text, *str, **str_list; + + mb_text = (char *) text; + str_list = (char **) list; + + for (str = *str_list; count > 0; count--, str_list++) { + strcpy(str, mb_text); + *str_list = str; + length = strlen(str) + 1; + str += length; + mb_text += length; + } + } +} + +static int +_XTextPropertyToTextList(lcd, dpy, text_prop, to_type, list_ret, count_ret) + XLCd lcd; + Display *dpy; + XTextProperty *text_prop; + char *to_type; + XPointer **list_ret; + int *count_ret; +{ + XlcConv conv; + char *from_type; + XPointer from, to, buf; + char *str_ptr, *last_ptr; + Atom encoding; + int from_left, to_left, buf_len, ret; + int unconv_num, nitems = text_prop->nitems; + Bool is_wide_char = False; + + if (strcmp(XlcNWideChar, to_type) == 0) + is_wide_char = True; + + if (nitems <= 0) { + *list_ret = NULL; + *count_ret = 0; + return Success; + } + + if (text_prop->format != 8) + return XConverterNotFound; + + encoding = text_prop->encoding; + if (encoding == XA_STRING) + from_type = XlcNString; + else if (encoding == XInternAtom(dpy, "COMPOUND_TEXT", False)) + from_type = XlcNCompoundText; + else if (encoding == XInternAtom(dpy, XLC_PUBLIC(lcd, encoding_name), False)) + from_type = XlcNMultiByte; + else + return XConverterNotFound; + + if (is_wide_char) { + buf_len = text_prop->nitems + 1; + buf = (XPointer) Xmalloc(buf_len * sizeof(wchar_t)); + } else { + buf_len = text_prop->nitems * XLC_PUBLIC(lcd, mb_cur_max) + 1; + buf = (XPointer) Xmalloc(buf_len); + } + if (buf == NULL) + return XNoMemory; + to = buf; + to_left = buf_len; + + conv = _XlcOpenConverter(lcd, from_type, lcd, to_type); + if (conv == NULL) { + Xfree(buf); + return XConverterNotFound; + } + + last_ptr = str_ptr = (char *) text_prop->value; + unconv_num = *count_ret = 0; + + while (1) { + if (nitems == 0 || *str_ptr == 0) { + from = (XPointer) last_ptr; + from_left = str_ptr - last_ptr; + last_ptr = str_ptr; + + ret = _XlcConvert(conv, &from, &from_left, &to, &to_left, NULL, 0); + + if (ret < 0) + continue; + + unconv_num += ret; + (*count_ret)++; + + if (nitems == 0) + break; + last_ptr = ++str_ptr; + if (is_wide_char) { + *((wchar_t *)to) = (wchar_t) 0; + to += sizeof(wchar_t); + to_left -= sizeof(wchar_t); + } else { + *((char *)to) = '\0'; + to++; + to_left--; + } + _XlcResetConverter(conv); + } else + str_ptr++; + + nitems--; + } + + _XlcCloseConverter(conv); + + if (is_wide_char) + *((wchar_t *) to) = (wchar_t) 0; + else + *((char *) to) = '\0'; + to_left--; + + *list_ret = alloc_list(is_wide_char, *count_ret, buf_len - to_left); + if (*list_ret) + copy_list(is_wide_char, buf, *list_ret, *count_ret); + + Xfree(buf); + + return unconv_num; +} + +int +_XmbTextPropertyToTextList(lcd, dpy, text_prop, list_ret, count_ret) + XLCd lcd; + Display *dpy; + XTextProperty *text_prop; + char ***list_ret; + int *count_ret; +{ + return _XTextPropertyToTextList(lcd, dpy, text_prop, XlcNMultiByte, + (XPointer **) list_ret, count_ret); +} + +int +_XwcTextPropertyToTextList(lcd, dpy, text_prop, list_ret, count_ret) + XLCd lcd; + Display *dpy; + XTextProperty *text_prop; + wchar_t ***list_ret; + int *count_ret; +{ + return _XTextPropertyToTextList(lcd, dpy, text_prop, XlcNWideChar, + (XPointer **) list_ret, count_ret); +} + +void +_XwcFreeStringList(lcd, list) + XLCd lcd; + wchar_t **list; +{ + if (list) { + if (*list) + Xfree(*list); + Xfree(list); + } +} diff --git a/src/xlibi18n/lcPubWrap.c b/src/xlibi18n/lcPubWrap.c new file mode 100644 index 00000000..f9eeb244 --- /dev/null +++ b/src/xlibi18n/lcPubWrap.c @@ -0,0 +1,104 @@ +/* $Xorg: lcPubWrap.c,v 1.3 2000/08/17 19:45:18 cpqbld Exp $ */ +/* + * Copyright 1992, 1993 by TOSHIBA Corp. + * + * 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 TOSHIBA not be used in advertising + * or publicity pertaining to distribution of the software without specific, + * written prior permission. TOSHIBA make no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * TOSHIBA DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING + * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL + * TOSHIBA 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. + * + * Author: Katsuhisa Yano TOSHIBA Corp. + * mopi@osa.ilab.toshiba.co.jp + */ + +#include "Xlibint.h" +#include "XlcPubI.h" + +#if NeedVarargsPrototypes +char * +_XGetLCValues(XLCd lcd, ...) +#else +char * +_XGetLCValues(lcd, va_alist) + XLCd lcd; + va_dcl +#endif +{ + va_list var; + XlcArgList args; + char *ret; + int num_args; + XLCdPublicMethodsPart *methods = XLC_PUBLIC_METHODS(lcd); + + Va_start(var, lcd); + _XlcCountVaList(var, &num_args); + va_end(var); + + Va_start(var, lcd); + _XlcVaToArgList(var, num_args, &args); + va_end(var); + + if (args == (XlcArgList) NULL) + return (char *) NULL; + + ret = (*methods->get_values)(lcd, args, num_args); + + Xfree(args); + + return ret; +} + +void +_XlcDestroyLC(lcd) + XLCd lcd; +{ + XLCdPublicMethods methods = (XLCdPublicMethods) lcd->methods; + + (*methods->pub.destroy)(lcd); +} + +XLCd +_XlcCreateLC(name, methods) + char *name; + XLCdMethods methods; +{ + XLCdPublicMethods pub_methods = (XLCdPublicMethods) methods; + XLCd lcd; + + lcd = (*pub_methods->pub.create)(name, methods); + if (lcd == NULL) + return (XLCd) NULL; + + if (lcd->core->name == NULL) { + lcd->core->name = (char*) Xmalloc(strlen(name) + 1); + if (lcd->core->name == NULL) + goto err; + strcpy(lcd->core->name, name); + } + + if (lcd->methods == NULL) + lcd->methods = methods; + + if ((*pub_methods->pub.initialize)(lcd) == False) + goto err; + + return lcd; + +err: + _XlcDestroyLC(lcd); + + return (XLCd) NULL; +} diff --git a/src/xlibi18n/lcPublic.c b/src/xlibi18n/lcPublic.c new file mode 100644 index 00000000..c72669ef --- /dev/null +++ b/src/xlibi18n/lcPublic.c @@ -0,0 +1,308 @@ +/* $Xorg: lcPublic.c,v 1.4 2000/12/12 12:44:05 coskrey Exp $ */ +/* + * Copyright 1992, 1993 by TOSHIBA Corp. + * + * 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 TOSHIBA not be used in advertising + * or publicity pertaining to distribution of the software without specific, + * written prior permission. TOSHIBA make no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * TOSHIBA DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING + * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL + * TOSHIBA 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. + * + * Author: Katsuhisa Yano TOSHIBA Corp. + * mopi@osa.ilab.toshiba.co.jp + */ + +#include <stdio.h> +#include "Xlibint.h" +#include "XlcPubI.h" + +static char *default_string(); + +static XLCd create(); +static Bool initialize(); +static void destroy(); +static char *get_values(); + +static XLCdPublicMethodsRec publicMethods = { + { + destroy, + _XlcDefaultMapModifiers, + NULL, + NULL, + _XrmDefaultInitParseInfo, + _XmbTextPropertyToTextList, + _XwcTextPropertyToTextList, + _XmbTextListToTextProperty, + _XwcTextListToTextProperty, + _XwcFreeStringList, + default_string, + NULL, + NULL + }, + { + NULL, + create, + initialize, + destroy, + get_values, + _XlcGetLocaleDataBase + } +}; + +XLCdMethods _XlcPublicMethods = (XLCdMethods) &publicMethods; + +static char * +default_string(lcd) + XLCd lcd; +{ + return XLC_PUBLIC(lcd, default_string); +} + +static XLCd +create(name, methods) + char *name; + XLCdMethods methods; +{ + XLCd lcd; + XLCdPublicMethods new; + + lcd = (XLCd) Xmalloc(sizeof(XLCdRec)); + if (lcd == NULL) + return (XLCd) NULL; + bzero((char *) lcd, sizeof(XLCdRec)); + + lcd->core = (XLCdCore) Xmalloc(sizeof(XLCdPublicRec)); + if (lcd->core == NULL) + goto err; + bzero((char *) lcd->core, sizeof(XLCdPublicRec)); + + new = (XLCdPublicMethods) Xmalloc(sizeof(XLCdPublicMethodsRec)); + if (new == NULL) + goto err; + *new = *((XLCdPublicMethods) methods); + lcd->methods = (XLCdMethods) new; + + return lcd; + +err: + Xfree(lcd); + return (XLCd) NULL; +} + +static Bool +load_public(lcd) + XLCd lcd; +{ + XLCdPublicPart *pub = XLC_PUBLIC_PART(lcd); + char **values, *str; + int num; + + if(_XlcCreateLocaleDataBase(lcd) == NULL) + return False; + + _XlcGetResource(lcd, "XLC_XLOCALE", "mb_cur_max", &values, &num); + if (num > 0) { + pub->mb_cur_max = atoi(values[0]); + if (pub->mb_cur_max < 1) + pub->mb_cur_max = 1; + } else + pub->mb_cur_max = 1; + + _XlcGetResource(lcd, "XLC_XLOCALE", "state_depend_encoding", &values, &num); + if (num > 0 && !_XlcCompareISOLatin1(values[0], "True")) + pub->is_state_depend = True; + else + pub->is_state_depend = False; + + _XlcGetResource(lcd, "XLC_XLOCALE", "encoding_name", &values, &num); + str = (num > 0) ? values[0] : "STRING"; + pub->encoding_name = (char*) Xmalloc(strlen(str) + 1); + if (pub->encoding_name == NULL) + return False; + strcpy(pub->encoding_name, str); + + return True; +} + +static Bool +initialize_core(lcd) + XLCd lcd; +{ + XLCdMethods methods = lcd->methods; + XLCdMethods core = &publicMethods.core; + + if (methods->close == NULL) + methods->close = core->close; + + if (methods->map_modifiers == NULL) + methods->map_modifiers = core->map_modifiers; + + if (methods->open_om == NULL) +#ifdef USE_DYNAMIC_LC + _XInitDefaultOM(lcd); +#else + _XInitOM(lcd); +#endif + + if (methods->open_im == NULL) +#ifdef USE_DYNAMIC_LC + _XInitDefaultIM(lcd); +#else + _XInitIM(lcd); +#endif + + if (methods->init_parse_info == NULL) + methods->init_parse_info = core->init_parse_info; + + if (methods->mb_text_prop_to_list == NULL) + methods->mb_text_prop_to_list = core->mb_text_prop_to_list; + + if (methods->wc_text_prop_to_list == NULL) + methods->wc_text_prop_to_list = core->wc_text_prop_to_list; + + if (methods->mb_text_list_to_prop == NULL) + methods->mb_text_list_to_prop = core->mb_text_list_to_prop; + + if (methods->wc_text_list_to_prop == NULL) + methods->wc_text_list_to_prop = core->wc_text_list_to_prop; + + if (methods->wc_free_string_list == NULL) + methods->wc_free_string_list = core->wc_free_string_list; + + if (methods->default_string == NULL) + methods->default_string = core->default_string; + + return True; +} + +extern Bool _XlcInitCTInfo(); + +static Bool +initialize(lcd) + XLCd lcd; +{ + XLCdPublicMethodsPart *methods = XLC_PUBLIC_METHODS(lcd); + XLCdPublicMethodsPart *pub_methods = &publicMethods.pub; + XLCdPublicPart *pub = XLC_PUBLIC_PART(lcd); + char *name; +#if !defined(X_NOT_STDC_ENV) && !defined(X_LOCALE) + int len; + char sinamebuf[256]; + char* siname; + char *_XlcMapOSLocaleName(); +#endif + + _XlcInitCTInfo(); + + if (initialize_core(lcd) == False) + return False; + + name = lcd->core->name; +#if !defined(X_NOT_STDC_ENV) && !defined(X_LOCALE) + /* + * _XlMapOSLOcaleName will return the same string or a substring + * of name, so strlen(name) is okay + */ + if ((len = strlen(name)) < sizeof sinamebuf) siname = sinamebuf; + else siname = Xmalloc (len + 1); + if (siname == NULL) return False; + name = _XlcMapOSLocaleName(name, siname); +#endif + /* _XlcResolveLocaleName will lookup the SI's name for the locale */ + if (_XlcResolveLocaleName(name, pub) == 0) { +#if !defined(X_NOT_STDC_ENV) && !defined(X_LOCALE) + if (siname != sinamebuf) Xfree (siname); +#endif + return False; + } +#if !defined(X_NOT_STDC_ENV) && !defined(X_LOCALE) + if (siname != sinamebuf) Xfree (siname); +#endif + + if (pub->default_string == NULL) + pub->default_string = ""; + + if (methods->get_values == NULL) + methods->get_values = pub_methods->get_values; + + if (methods->get_resource == NULL) + methods->get_resource = pub_methods->get_resource; + + return load_public(lcd); +} + +static void +destroy_core(lcd) + XLCd lcd; +{ + if (lcd->core) { + if (lcd->core->name) + Xfree(lcd->core->name); + Xfree(lcd->core); + } + + if (lcd->methods) + Xfree(lcd->methods); + + Xfree(lcd); +} + +static void +destroy(lcd) + XLCd lcd; +{ + XLCdPublicPart *pub = XLC_PUBLIC_PART(lcd); + + _XlcDestroyLocaleDataBase(lcd); + + if (pub->siname) + Xfree(pub->siname); + if (pub->encoding_name) + Xfree(pub->encoding_name); + + destroy_core(lcd); +} + +static XlcResource resources[] = { + { XlcNCodeset, NULLQUARK, sizeof(char *), + XOffsetOf(XLCdPublicRec, pub.codeset), XlcGetMask }, + { XlcNDefaultString, NULLQUARK, sizeof(char *), + XOffsetOf(XLCdPublicRec, pub.default_string), XlcGetMask }, + { XlcNEncodingName, NULLQUARK, sizeof(char *), + XOffsetOf(XLCdPublicRec, pub.encoding_name), XlcGetMask }, + { XlcNLanguage, NULLQUARK, sizeof(char *), + XOffsetOf(XLCdPublicRec, pub.language), XlcGetMask }, + { XlcNMbCurMax, NULLQUARK, sizeof(int), + XOffsetOf(XLCdPublicRec, pub.mb_cur_max), XlcGetMask }, + { XlcNStateDependentEncoding, NULLQUARK, sizeof(Bool), + XOffsetOf(XLCdPublicRec, pub.is_state_depend), XlcGetMask }, + { XlcNTerritory, NULLQUARK, sizeof(char *), + XOffsetOf(XLCdPublicRec, pub.territory), XlcGetMask } +}; + +static char * +get_values(lcd, args, num_args) + register XLCd lcd; + register XlcArgList args; + register int num_args; +{ + XLCdPublic pub = (XLCdPublic) lcd->core; + + if (resources[0].xrm_name == NULLQUARK) + _XlcCompileResourceList(resources, XlcNumber(resources)); + + return _XlcGetValues((XPointer) pub, resources, XlcNumber(resources), args, + num_args, XlcGetMask); +} diff --git a/src/xlibi18n/lcRM.c b/src/xlibi18n/lcRM.c new file mode 100644 index 00000000..0824a6f7 --- /dev/null +++ b/src/xlibi18n/lcRM.c @@ -0,0 +1,122 @@ +/* $Xorg: lcRM.c,v 1.3 2000/08/17 19:45:19 cpqbld Exp $ */ +/* + * Copyright 1992, 1993 by TOSHIBA Corp. + * + * 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 TOSHIBA not be used in advertising + * or publicity pertaining to distribution of the software without specific, + * written prior permission. TOSHIBA make no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * TOSHIBA DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING + * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL + * TOSHIBA 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. + * + * Author: Katsuhisa Yano TOSHIBA Corp. + * mopi@osa.ilab.toshiba.co.jp + */ + +#include "Xlibint.h" +#include "XlcPubI.h" +#include <stdio.h> + +typedef struct _StateRec { + XLCd lcd; + XlcConv conv; +} StateRec, *State; + +static void +mbinit(state) + XPointer state; +{ + _XlcResetConverter(((State) state)->conv); +} + +static char +mbchar(state, str, lenp) + XPointer state; + char *str; + int *lenp; +{ + XlcConv conv = ((State) state)->conv; + XlcCharSet charset; + char *from, *to, buf[BUFSIZ]; + int from_left, to_left; + XPointer args[1]; + + from = str; + *lenp = from_left = XLC_PUBLIC(((State) state)->lcd, mb_cur_max); + to = buf; + to_left = BUFSIZ; + args[0] = (XPointer) &charset; + + _XlcConvert(conv, (XPointer *) &from, &from_left, (XPointer *) &to, + &to_left, args, 1); + + *lenp -= from_left; + + /* XXX */ + return buf[0]; +} + +static void +mbfinish(state) + XPointer state; +{ +} + +static char * +lcname(state) + XPointer state; +{ + return ((State) state)->lcd->core->name; +} + +static void +destroy(state) + XPointer state; +{ + _XlcCloseConverter(((State) state)->conv); + _XCloseLC(((State) state)->lcd); + Xfree((char *) state); +} + +static XrmMethodsRec rm_methods = { + mbinit, + mbchar, + mbfinish, + lcname, + destroy +} ; + +XrmMethods +_XrmDefaultInitParseInfo(lcd, rm_state) + XLCd lcd; + XPointer *rm_state; +{ + State state; + + state = (State) Xmalloc(sizeof(StateRec)); + if (state == NULL) + return (XrmMethods) NULL; + + state->lcd = lcd; + state->conv = _XlcOpenConverter(lcd, XlcNMultiByte, lcd, XlcNChar); + if (state->conv == NULL) { + Xfree((char *) state); + + return (XrmMethods) NULL; + } + + *rm_state = (XPointer) state; + + return &rm_methods; +} diff --git a/src/xlibi18n/lcStd.c b/src/xlibi18n/lcStd.c new file mode 100644 index 00000000..9d938d39 --- /dev/null +++ b/src/xlibi18n/lcStd.c @@ -0,0 +1,305 @@ +/* $Xorg: lcStd.c,v 1.4 2000/08/17 19:45:20 cpqbld Exp $ */ +/* + * Copyright 1992, 1993 by TOSHIBA Corp. + * + * 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 TOSHIBA not be used in advertising + * or publicity pertaining to distribution of the software without specific, + * written prior permission. TOSHIBA make no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * TOSHIBA DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING + * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL + * TOSHIBA 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. + * + * Author: Katsuhisa Yano TOSHIBA Corp. + * mopi@osa.ilab.toshiba.co.jp + */ + +#include "Xlibint.h" +#include "XlcPubI.h" + +int +_Xlcmbtowc(lcd, wstr, str, len) + XLCd lcd; + wchar_t *wstr; + char *str; + int len; +{ + static XLCd last_lcd = NULL; + static XlcConv conv = NULL; + XPointer from, to; + int from_left, to_left; + wchar_t tmp_wc; + + if (lcd == NULL) { + lcd = _XlcCurrentLC(); + if (lcd == NULL) + return -1; + } + if (str == NULL) + return XLC_PUBLIC(lcd, is_state_depend); + + if (conv && lcd != last_lcd) { + _XlcCloseConverter(conv); + conv = NULL; + } + + last_lcd = lcd; + + if (conv == NULL) { + conv = _XlcOpenConverter(lcd, XlcNMultiByte, lcd, XlcNWideChar); + if (conv == NULL) + return -1; + } + + from = (XPointer) str; + from_left = len; + to = (XPointer) (wstr ? wstr : &tmp_wc); + to_left = 1; + + if (_XlcConvert(conv, &from, &from_left, &to, &to_left, NULL, 0) < 0) + return -1; + + return (len - from_left); +} + +int +_Xlcwctomb(lcd, str, wc) + XLCd lcd; + char *str; + wchar_t wc; +{ + static XLCd last_lcd = NULL; + static XlcConv conv = NULL; + XPointer from, to; + int from_left, to_left, length; + + if (lcd == NULL) { + lcd = _XlcCurrentLC(); + if (lcd == NULL) + return -1; + } + if (str == NULL) + return XLC_PUBLIC(lcd, is_state_depend); + + if (conv && lcd != last_lcd) { + _XlcCloseConverter(conv); + conv = NULL; + } + + last_lcd = lcd; + + if (conv == NULL) { + conv = _XlcOpenConverter(lcd, XlcNWideChar, lcd, XlcNMultiByte); + if (conv == NULL) + return -1; + } + + from = (XPointer) &wc; + from_left = 1; + to = (XPointer) str; + length = to_left = XLC_PUBLIC(lcd, mb_cur_max); + + if (_XlcConvert(conv, &from, &from_left, &to, &to_left, NULL, 0) < 0) + return -1; + + return (length - to_left); +} + +int +_Xlcmbstowcs(lcd, wstr, str, len) + XLCd lcd; + wchar_t *wstr; + char *str; + int len; +{ + XlcConv conv; + XPointer from, to; + int from_left, to_left, ret; + + if (lcd == NULL) { + lcd = _XlcCurrentLC(); + if (lcd == NULL) + return -1; + } + + conv = _XlcOpenConverter(lcd, XlcNMultiByte, lcd, XlcNWideChar); + if (conv == NULL) + return -1; + + from = (XPointer) str; + from_left = strlen(str); + to = (XPointer) wstr; + to_left = len; + + if (_XlcConvert(conv, &from, &from_left, &to, &to_left, NULL, 0) < 0) + ret = -1; + else { + ret = len - to_left; + if (wstr && to_left > 0) + wstr[ret] = (wchar_t) 0; + } + + _XlcCloseConverter(conv); + + return ret; +} + +int +_Xlcwcstombs(lcd, str, wstr, len) + XLCd lcd; + char *str; + wchar_t *wstr; + int len; +{ + XlcConv conv; + XPointer from, to; + int from_left, to_left, ret; + + if (lcd == NULL) { + lcd = _XlcCurrentLC(); + if (lcd == NULL) + return -1; + } + + conv = _XlcOpenConverter(lcd, XlcNWideChar, lcd, XlcNMultiByte); + if (conv == NULL) + return -1; + + from = (XPointer) wstr; + from_left = _Xwcslen(wstr); + to = (XPointer) str; + to_left = len; + + if (_XlcConvert(conv, &from, &from_left, &to, &to_left, NULL, 0) < 0) + ret = -1; + else { + ret = len - to_left; + if (str && to_left > 0) + str[ret] = '\0'; + } + + _XlcCloseConverter(conv); + + return ret; +} + + +int +_Xmbtowc(wstr, str, len) + wchar_t *wstr; + char *str; + int len; +{ + return _Xlcmbtowc((XLCd) NULL, wstr, str, len); +} + +int +_Xmblen(str, len) + char *str; + int len; +{ + return _Xmbtowc((wchar_t *) NULL, str, len); +} + +int +_Xwctomb(str, wc) + char *str; + wchar_t wc; +{ + return _Xlcwctomb((XLCd) NULL, str, wc); +} + +int +_Xmbstowcs(wstr, str, len) + wchar_t *wstr; + char *str; + int len; +{ + return _Xlcmbstowcs((XLCd) NULL, wstr, str, len); +} + +int +_Xwcstombs(str, wstr, len) + char *str; + wchar_t *wstr; + int len; +{ + return _Xlcwcstombs((XLCd) NULL, str, wstr, len); +} + +wchar_t * +_Xwcscpy(wstr1, wstr2) + register wchar_t *wstr1, *wstr2; +{ + wchar_t *wstr_tmp = wstr1; + + while ((*wstr1++ = *wstr2++)) + ; + + return wstr_tmp; +} + +wchar_t * +_Xwcsncpy(wstr1, wstr2, len) + register wchar_t *wstr1, *wstr2; + register int len; +{ + wchar_t *wstr_tmp = wstr1; + + while (len-- > 0) + if (!(*wstr1++ = *wstr2++)) + break; + + while (len-- > 0) + *wstr1++ = (wchar_t) 0; + + return wstr_tmp; +} + +int +_Xwcslen(wstr) + register wchar_t *wstr; +{ + register wchar_t *wstr_ptr = wstr; + + while (*wstr_ptr) + wstr_ptr++; + + return wstr_ptr - wstr; +} + +int +_Xwcscmp(wstr1, wstr2) + register wchar_t *wstr1, *wstr2; +{ + for ( ; *wstr1 && *wstr2; wstr1++, wstr2++) + if (*wstr1 != *wstr2) + break; + + return *wstr1 - *wstr2; +} + +int +_Xwcsncmp(wstr1, wstr2, len) + register wchar_t *wstr1, *wstr2; + register int len; +{ + for ( ; *wstr1 && *wstr2 && len > 0; wstr1++, wstr2++, len--) + if (*wstr1 != *wstr2) + break; + + if (len <= 0) + return 0; + + return *wstr1 - *wstr2; +} diff --git a/src/xlibi18n/lcTxtPr.c b/src/xlibi18n/lcTxtPr.c new file mode 100644 index 00000000..1efdb278 --- /dev/null +++ b/src/xlibi18n/lcTxtPr.c @@ -0,0 +1,235 @@ +/* $Xorg: lcTxtPr.c,v 1.3 2000/08/17 19:45:20 cpqbld Exp $ */ +/* + * Copyright 1992, 1993 by TOSHIBA Corp. + * + * 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 TOSHIBA not be used in advertising + * or publicity pertaining to distribution of the software without specific, + * written prior permission. TOSHIBA make no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * TOSHIBA DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING + * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL + * TOSHIBA 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. + * + * Author: Katsuhisa Yano TOSHIBA Corp. + * mopi@osa.ilab.toshiba.co.jp + */ + +#include "Xlibint.h" +#include "XlcPubI.h" +#include <X11/Xutil.h> +#include <X11/Xatom.h> +#include <stdio.h> + +static int +get_buf_size(is_wide_char, list, count) + Bool is_wide_char; + XPointer list; + int count; +{ + register int length = 0; + register char **mb_list; + register wchar_t **wc_list; + + if (list == NULL) + return 0; + + if (is_wide_char) { + wc_list = (wchar_t **) list; + for ( ; count-- > 0; wc_list++) { + if (*wc_list) + length += _Xwcslen(*wc_list) + 1; + } + length *= 5; /* XXX */ + } else { + mb_list = (char **) list; + for ( ; count-- > 0; mb_list++) { + if (*mb_list) + length += strlen(*mb_list) + 1; + } + length *= 3; /* XXX */ + } + length = (length / BUFSIZ + 1) * BUFSIZ; /* XXX */ + + return length; +} + +static int +_XTextListToTextProperty(lcd, dpy, from_type, list, count, style, text_prop) + XLCd lcd; + Display *dpy; + char *from_type; + XPointer list; + int count; + XICCEncodingStyle style; + XTextProperty *text_prop; +{ + Atom encoding; + XlcConv conv; + char *to_type; + char **mb_list; + wchar_t **wc_list; + XPointer from; + char *to, *buf, *value; + int from_left, to_left, buf_len, nitems, unconv_num, ret, i; + Bool is_wide_char = False; + + if (strcmp(XlcNWideChar, from_type) == 0) + is_wide_char = True; + + buf_len = get_buf_size(is_wide_char, list, count); + if ((buf = (char *) Xmalloc(buf_len)) == NULL) + return XNoMemory; + + switch (style) { + case XStringStyle: + case XStdICCTextStyle: + encoding = XA_STRING; + to_type = XlcNString; + break; + case XCompoundTextStyle: + encoding = XInternAtom(dpy, "COMPOUND_TEXT", False); + to_type = XlcNCompoundText; + break; + case XTextStyle: + encoding = XInternAtom(dpy, XLC_PUBLIC(lcd, encoding_name), False); + to_type = XlcNMultiByte; + if (is_wide_char == False) { + nitems = 0; + mb_list = (char **) list; + to = buf; + for (i = 0; i < count && buf_len > 0; i++) { + if (*mb_list) + strcpy(to, *mb_list); + else + *to = '\0'; + from_left = (*mb_list ? strlen(*mb_list) : 0) + 1; + nitems += from_left; + to += from_left; + mb_list++; + } + unconv_num = 0; + goto done; + } + break; + default: + Xfree(buf); + return XConverterNotFound; + } + + if (count < 1) { + nitems = 0; + goto done; + } + +retry: + conv = _XlcOpenConverter(lcd, from_type, lcd, to_type); + if (conv == NULL) { + Xfree(buf); + return XConverterNotFound; + } + + if (is_wide_char) + wc_list = (wchar_t **) list; + else + mb_list = (char **) list; + + to = buf; + to_left = buf_len; + + unconv_num = 0; + + for (i = 1; to_left > 0; i++) { + if (is_wide_char) { + from = (XPointer) *wc_list; + from_left = _Xwcslen(*wc_list); + wc_list++; + } else { + from = (XPointer) *mb_list; + from_left = (*mb_list ? strlen(*mb_list) : 0); + mb_list++; + } + + ret = _XlcConvert(conv, &from, &from_left, (XPointer *) &to, &to_left, + NULL, 0); + + if (ret < 0) + continue; + + if (ret > 0 && style == XStdICCTextStyle && encoding == XA_STRING) { + _XlcCloseConverter(conv); + encoding = XInternAtom(dpy, "COMPOUND_TEXT", False); + to_type = XlcNCompoundText; + goto retry; + } + + unconv_num += ret; + *to++ = '\0'; + to_left--; + + if (i >= count) + break; + + _XlcResetConverter(conv); + } + + _XlcCloseConverter(conv); + + nitems = to - buf; +done: + if (nitems <= 0) + nitems = 1; + value = (char *) Xmalloc(nitems); + if (value == NULL) { + Xfree(buf); + return XNoMemory; + } + if (nitems == 1) + *value = 0; + else + memcpy(value, buf, nitems); + nitems--; + Xfree(buf); + + text_prop->value = (unsigned char *) value; + text_prop->encoding = encoding; + text_prop->format = 8; + text_prop->nitems = nitems; + + return unconv_num; +} + +int +_XmbTextListToTextProperty(lcd, dpy, list, count, style, text_prop) + XLCd lcd; + Display *dpy; + char **list; + int count; + XICCEncodingStyle style; + XTextProperty *text_prop; +{ + return _XTextListToTextProperty(lcd, dpy, XlcNMultiByte, (XPointer) list, + count, style, text_prop); +} + +int +_XwcTextListToTextProperty(lcd, dpy, list, count, style, text_prop) + XLCd lcd; + Display *dpy; + wchar_t **list; + int count; + XICCEncodingStyle style; + XTextProperty *text_prop; +{ + return _XTextListToTextProperty(lcd, dpy, XlcNWideChar, (XPointer) list, + count, style, text_prop); +} diff --git a/src/xlibi18n/lcUtil.c b/src/xlibi18n/lcUtil.c new file mode 100644 index 00000000..cb439b0b --- /dev/null +++ b/src/xlibi18n/lcUtil.c @@ -0,0 +1,78 @@ +/* $Xorg: lcUtil.c,v 1.3 2000/08/17 19:45:20 cpqbld Exp $ */ +/* + * Copyright 1992, 1993 by TOSHIBA Corp. + * + * 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 TOSHIBA not be used in advertising + * or publicity pertaining to distribution of the software without specific, + * written prior permission. TOSHIBA make no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * TOSHIBA DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING + * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL + * TOSHIBA 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. + * + * Author: Katsuhisa Yano TOSHIBA Corp. + * mopi@osa.ilab.toshiba.co.jp + */ + +#include <stdio.h> +#include <ctype.h> +#include <X11/Xos.h> +#include "Xlibint.h" + +#ifdef X_NOT_STDC_ENV +#ifndef toupper +#define toupper(c) ((int)(c) - 'a' + 'A') +#endif +#endif + +int +_XlcCompareISOLatin1(str1, str2) + char *str1, *str2; +{ + register char ch1, ch2; + + for ( ; (ch1 = *str1) && (ch2 = *str2); str1++, str2++) { + if (islower(ch1)) + ch1 = toupper(ch1); + if (islower(ch2)) + ch2 = toupper(ch2); + + if (ch1 != ch2) + break; + } + + return *str1 - *str2; +} + +int +_XlcNCompareISOLatin1(str1, str2, len) + char *str1, *str2; + int len; +{ + register char ch1, ch2; + + for ( ; (ch1 = *str1) && (ch2 = *str2) && len; str1++, str2++, len--) { + if (islower(ch1)) + ch1 = toupper(ch1); + if (islower(ch2)) + ch2 = toupper(ch2); + + if (ch1 != ch2) + break; + } + + if (len == 0) + return 0; + + return *str1 - *str2; +} diff --git a/src/xlibi18n/lcWrap.c b/src/xlibi18n/lcWrap.c new file mode 100644 index 00000000..d2dcfe94 --- /dev/null +++ b/src/xlibi18n/lcWrap.c @@ -0,0 +1,620 @@ +/* $Xorg: lcWrap.c,v 1.6 2001/02/09 02:03:39 xorgcvs Exp $ */ +/* + +Copyright 1991, 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 1991 by the Open Software Foundation + * Copyright 1993 by the TOSHIBA Corp. + * + * 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 names of Open Software Foundation and TOSHIBA + * not be used in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. Open Software + * Foundation and TOSHIBA make no representations about the suitability of this + * software for any purpose. It is provided "as is" without express or + * implied warranty. + * + * OPEN SOFTWARE FOUNDATION AND TOSHIBA DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL OPEN SOFTWARE FOUNDATIONN OR TOSHIBA 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. + * + * M. Collins OSF + * + * Katsuhisa Yano TOSHIBA Corp. + */ + +#include "Xlibint.h" +#include "Xlcint.h" +#include <X11/Xlocale.h> +#include <X11/Xos.h> +#ifdef WIN32 +#undef close +#endif +#include <X11/Xutil.h> + +#ifdef __STDC__ +#define Const const +#else +#define Const /**/ +#endif + +#ifdef X_NOT_STDC_ENV +extern char *getenv(); +#endif + +extern void _XlcInitLoader( +#if NeedFunctionPrototypes + char* +#endif +); + +#ifdef XTHREADS +LockInfoPtr _Xi18n_lock; +#endif + +#if NeedFunctionPrototypes +char * +XSetLocaleModifiers( + _Xconst char *modifiers +) +#else +char * +XSetLocaleModifiers(modifiers) + char *modifiers; +#endif +{ + XLCd lcd = _XlcCurrentLC(); + char *user_mods; + + if (!lcd) + return (char *) NULL; + if (!modifiers) + return lcd->core->modifiers; + user_mods = getenv("XMODIFIERS"); + modifiers = (*lcd->methods->map_modifiers) (lcd, + user_mods, (char *)modifiers); + if (modifiers) { + if (lcd->core->modifiers) + Xfree(lcd->core->modifiers); + lcd->core->modifiers = (char *)modifiers; + } + return (char *)modifiers; +} + +Bool +XSupportsLocale() +{ + return _XlcCurrentLC() != (XLCd)NULL; +} + +Bool _XlcValidModSyntax(mods, valid_mods) + char *mods; + char **valid_mods; +{ + int i; + char **ptr; + + while (mods && (*mods == '@')) { + mods++; + if (*mods == '@') + break; + for (ptr = valid_mods; *ptr; ptr++) { + i = strlen(*ptr); + if (strncmp(mods, *ptr, i) || ((mods[i] != '=') +#ifdef WIN32 + && (mods[i] != '#') +#endif + )) + continue; + mods = strchr(mods+i+1, '@'); + break; + } + } + return !mods || !*mods; +} + +static Const char *im_valid[] = {"im", (char *)NULL}; + +/*ARGSUSED*/ +char * +_XlcDefaultMapModifiers (lcd, user_mods, prog_mods) + XLCd lcd; + char *user_mods; + char *prog_mods; +{ + int i; + char *mods; + + if (!_XlcValidModSyntax(prog_mods, (char **)im_valid)) + return (char *)NULL; + if (!_XlcValidModSyntax(user_mods, (char **)im_valid)) + return (char *)NULL; + i = strlen(prog_mods) + 1; + if (user_mods) + i += strlen(user_mods); + mods = Xmalloc(i); + if (mods) { + strcpy(mods, prog_mods); + if (user_mods) + strcat(mods, user_mods); +#ifdef WIN32 + { + char *s; + for (s = mods; s = strchr(s, '@'); s++) { + for (s++; *s && *s != '='; s++) { + if (*s == '#') { + *s = '='; + break; + } + } + } + } +#endif + } + return mods; +} + +typedef struct _XLCdListRec { + struct _XLCdListRec *next; + XLCd lcd; + int ref_count; +} XLCdListRec, *XLCdList; + +static XLCdList lcd_list = NULL; + +typedef struct _XlcLoaderListRec { + struct _XlcLoaderListRec *next; + XLCdLoadProc proc; +} XlcLoaderListRec, *XlcLoaderList; + +static XlcLoaderList loader_list = NULL; + +void +_XlcRemoveLoader(proc) + XLCdLoadProc proc; +{ + XlcLoaderList loader, prev; + + if (loader_list == NULL) + return; + + prev = loader = loader_list; + if (loader->proc == proc) { + loader_list = loader->next; + Xfree(loader); + return; + } + + while ((loader = loader->next)) { + if (loader->proc == proc) { + prev->next = loader->next; + Xfree(loader); + return; + } + prev = loader; + } + + return; +} + +Bool +_XlcAddLoader(proc, position) + XLCdLoadProc proc; + XlcPosition position; +{ + XlcLoaderList loader, last; + + _XlcRemoveLoader(proc); /* remove old loader, if exist */ + + loader = (XlcLoaderList) Xmalloc(sizeof(XlcLoaderListRec)); + if (loader == NULL) + return False; + + loader->proc = proc; + + if (loader_list == NULL) + position = XlcHead; + + if (position == XlcHead) { + loader->next = loader_list; + loader_list = loader; + } else { + last = loader_list; + while (last->next) + last = last->next; + + loader->next = NULL; + last->next = loader; + } + + return True; +} + +XLCd +_XOpenLC(name) + char *name; +{ + XLCd lcd; + XlcLoaderList loader; + XLCdList cur; +#if !defined(X_NOT_STDC_ENV) && !defined(X_LOCALE) + int len; + char sinamebuf[256]; + char* siname; + char *_XlcMapOSLocaleName(); +#endif + + if (name == NULL) { + name = setlocale (LC_CTYPE, (char *)NULL); +#if !defined(X_NOT_STDC_ENV) && !defined(X_LOCALE) + /* + * _XlMapOSLOcaleName will return the same string or a substring + * of name, so strlen(name) is okay + */ + if ((len = strlen(name)) < sizeof sinamebuf) siname = sinamebuf; + else siname = Xmalloc (len + 1); + if (siname == NULL) return NULL; + name = _XlcMapOSLocaleName(name, siname); +#endif + } + + _XLockMutex(_Xi18n_lock); + + /* + * search for needed lcd, if found return it + */ + for (cur = lcd_list; cur; cur = cur->next) { + if (!strcmp (cur->lcd->core->name, name)) { + lcd = cur->lcd; + cur->ref_count++; + goto found; + } + } + + _XlcInitLoader(name); + + /* + * not there, so try to get and add to list + */ + for (loader = loader_list; loader; loader = loader->next) { + lcd = (*loader->proc)(name); + if (lcd) { + cur = (XLCdList) Xmalloc (sizeof(XLCdListRec)); + if (cur) { + cur->lcd = lcd; + cur->ref_count = 1; + cur->next = lcd_list; + lcd_list = cur; + } else { + (*lcd->methods->close)(lcd); + lcd = (XLCd) NULL; + } + break; + } + } + +found: + _XUnlockMutex(_Xi18n_lock); + +#if !defined(X_NOT_STDC_ENV) && !defined(X_LOCALE) + if (siname != sinamebuf) Xfree(siname); +#endif + + return lcd; +} + +void +_XCloseLC(lcd) + XLCd lcd; +{ + XLCdList cur, *prev; + + for (prev = &lcd_list; (cur = *prev); prev = &cur->next) { + if (cur->lcd == lcd) { + if (--cur->ref_count < 1) { + (*lcd->methods->close)(lcd); + *prev = cur->next; + Xfree(cur); + } + break; + } + } +} + +/* + * Get the XLCd for the current locale + */ + +XLCd +_XlcCurrentLC() +{ + XLCd lcd; + static XLCd last_lcd = NULL; + + lcd = _XOpenLC((char *) NULL); + + if (last_lcd) + _XCloseLC(last_lcd); + + last_lcd = lcd; + + return lcd; +} + +XrmMethods +_XrmInitParseInfo(state) + XPointer *state; +{ + XLCd lcd = _XOpenLC((char *) NULL); + + if (lcd == (XLCd) NULL) + return (XrmMethods) NULL; + + return (*lcd->methods->init_parse_info)(lcd, state); +} + +int +XmbTextPropertyToTextList(dpy, text_prop, list_ret, count_ret) + Display *dpy; + XTextProperty *text_prop; + char ***list_ret; + int *count_ret; +{ + XLCd lcd = _XlcCurrentLC(); + + if (lcd == NULL) + return XLocaleNotSupported; + + return (*lcd->methods->mb_text_prop_to_list)(lcd, dpy, text_prop, list_ret, + count_ret); +} + +int +XwcTextPropertyToTextList(dpy, text_prop, list_ret, count_ret) + Display *dpy; + XTextProperty *text_prop; + wchar_t ***list_ret; + int *count_ret; +{ + XLCd lcd = _XlcCurrentLC(); + + if (lcd == NULL) + return XLocaleNotSupported; + + return (*lcd->methods->wc_text_prop_to_list)(lcd, dpy, text_prop, list_ret, + count_ret); +} + +int +XmbTextListToTextProperty(dpy, list, count, style, text_prop) + Display *dpy; + char **list; + int count; + XICCEncodingStyle style; + XTextProperty *text_prop; +{ + XLCd lcd = _XlcCurrentLC(); + + if (lcd == NULL) + return XLocaleNotSupported; + + return (*lcd->methods->mb_text_list_to_prop)(lcd, dpy, list, count, style, + text_prop); +} + +int +XwcTextListToTextProperty(dpy, list, count, style, text_prop) + Display *dpy; + wchar_t **list; + int count; + XICCEncodingStyle style; + XTextProperty *text_prop; +{ + XLCd lcd = _XlcCurrentLC(); + + if (lcd == NULL) + return XLocaleNotSupported; + + return (*lcd->methods->wc_text_list_to_prop)(lcd, dpy, list, count, style, + text_prop); +} + +void +XwcFreeStringList(list) + wchar_t **list; +{ + XLCd lcd = _XlcCurrentLC(); + + if (lcd == NULL) + return; + + (*lcd->methods->wc_free_string_list)(lcd, list); +} + +char * +XDefaultString() +{ + XLCd lcd = _XlcCurrentLC(); + + if (lcd == NULL) + return (char *) NULL; + + return (*lcd->methods->default_string)(lcd); +} + +void +_XlcCopyFromArg(src, dst, size) + char *src; + register char *dst; + register int size; +{ + if (size == sizeof(long)) + *((long *) dst) = (long) src; +#ifdef LONG64 + else if (size == sizeof(int)) + *((int *) dst) = (int) src; +#endif + else if (size == sizeof(short)) + *((short *) dst) = (short)(long) src; + else if (size == sizeof(char)) + *((char *) dst) = (char)(long) src; + else if (size == sizeof(XPointer)) + *((XPointer *) dst) = (XPointer) src; + else if (size > sizeof(XPointer)) + memcpy(dst, (char *) src, size); + else + memcpy(dst, (char *) &src, size); +} + +void +_XlcCopyToArg(src, dst, size) + register char *src; + register char **dst; + register int size; +{ + if (size == sizeof(long)) + *((long *) *dst) = *((long *) src); + else if (size == sizeof(short)) + *((short *) *dst) = *((short *) src); + else if (size == sizeof(char)) + *((char *) *dst) = *((char *) src); + else if (size == sizeof(XPointer)) + *((XPointer *) *dst) = *((XPointer *) src); + else + memcpy(*dst, src, size); +} + +void +_XlcCountVaList(var, count_ret) + va_list var; + int *count_ret; +{ + register int count; + + for (count = 0; va_arg(var, char *); count++) + va_arg(var, XPointer); + + *count_ret = count; +} + +void +_XlcVaToArgList(var, count, args_ret) + va_list var; + register int count; + XlcArgList *args_ret; +{ + register XlcArgList args; + + *args_ret = args = (XlcArgList) Xmalloc(sizeof(XlcArg) * count); + if (args == (XlcArgList) NULL) + return; + + for ( ; count-- > 0; args++) { + args->name = va_arg(var, char *); + args->value = va_arg(var, XPointer); + } +} + +void +_XlcCompileResourceList(resources, num_resources) + register XlcResourceList resources; + register int num_resources; +{ + for ( ; num_resources-- > 0; resources++) + resources->xrm_name = XrmPermStringToQuark(resources->name); +} + +char * +_XlcGetValues(base, resources, num_resources, args, num_args, mask) + XPointer base; + XlcResourceList resources; + int num_resources; + XlcArgList args; + int num_args; + unsigned long mask; +{ + XlcResourceList res; + XrmQuark xrm_name; + int count; + + for ( ; num_args-- > 0; args++) { + res = resources; + count = num_resources; + xrm_name = XrmPermStringToQuark(args->name); + + for ( ; count-- > 0; res++) { + if (xrm_name == res->xrm_name && (mask & res->mask)) { + _XlcCopyToArg(base + res->offset, &args->value, res->size); + break; + } + } + + if (count < 0) + return args->name; + } + + return NULL; +} + +char * +_XlcSetValues(base, resources, num_resources, args, num_args, mask) + XPointer base; + XlcResourceList resources; + int num_resources; + XlcArgList args; + int num_args; + unsigned long mask; +{ + XlcResourceList res; + XrmQuark xrm_name; + int count; + + for ( ; num_args-- > 0; args++) { + res = resources; + count = num_resources; + xrm_name = XrmPermStringToQuark(args->name); + + for ( ; count-- > 0; res++) { + if (xrm_name == res->xrm_name && (mask & res->mask)) { + _XlcCopyFromArg(args->value, base + res->offset, res->size); + break; + } + } + + if (count < 0) + return args->name; + } + + return NULL; +} diff --git a/src/xlibi18n/mbWMProps.c b/src/xlibi18n/mbWMProps.c new file mode 100644 index 00000000..be256575 --- /dev/null +++ b/src/xlibi18n/mbWMProps.c @@ -0,0 +1,84 @@ +/* $Xorg: mbWMProps.c,v 1.4 2001/02/09 02:03:40 xorgcvs Exp $ */ +/* + +Copyright 1991, 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. + +*/ + +#include <X11/Xlibint.h> +#include <X11/Xutil.h> +#include <X11/Xatom.h> +#include <X11/Xlocale.h> + +#if NeedFunctionPrototypes +void XmbSetWMProperties ( + Display *dpy, + Window w, + _Xconst char *windowName, + _Xconst char *iconName, + char **argv, + int argc, + XSizeHints *sizeHints, + XWMHints *wmHints, + XClassHint *classHints) +#else +void XmbSetWMProperties (dpy, w, windowName, iconName, argv, argc, sizeHints, + wmHints, classHints) + Display *dpy; + Window w; /* window to decorate */ + char *windowName; /* name of application */ + char *iconName; /* name string for icon */ + char **argv; /* command line */ + int argc; /* size of command line */ + XSizeHints *sizeHints; /* size hints for window in its normal state */ + XWMHints *wmHints; /* miscelaneous window manager hints */ + XClassHint *classHints; /* resource name and class */ +#endif +{ + XTextProperty wname, iname; + XTextProperty *wprop = NULL; + XTextProperty *iprop = NULL; + char *locale; + + if (windowName && + XmbTextListToTextProperty(dpy, (char**)&windowName, 1, + XStdICCTextStyle, &wname) >= Success) + wprop = &wname; + if (iconName && + XmbTextListToTextProperty(dpy, (char**)&iconName, 1, + XStdICCTextStyle, &iname) >= Success) + iprop = &iname; + XSetWMProperties(dpy, w, wprop, iprop, argv, argc, + sizeHints, wmHints, classHints); + if (wprop) + Xfree((char *)wname.value); + if (iprop) + Xfree((char *)iname.value); + locale = setlocale(LC_CTYPE, (char *)NULL); + if (locale) + XChangeProperty (dpy, w, XInternAtom(dpy, "WM_LOCALE_NAME", False), + XA_STRING, 8, PropModeReplace, + (unsigned char *)locale, strlen(locale)); +} diff --git a/src/xlibi18n/mbWrap.c b/src/xlibi18n/mbWrap.c new file mode 100644 index 00000000..f82ba212 --- /dev/null +++ b/src/xlibi18n/mbWrap.c @@ -0,0 +1,220 @@ +/* $Xorg: mbWrap.c,v 1.4 2001/02/09 02:03:40 xorgcvs Exp $ */ +/* + +Copyright 1991, 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 1991 by the Open Software Foundation + * + * 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 Open Software Foundation + * not be used in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. Open Software + * Foundation makes no representations about the suitability of this + * software for any purpose. It is provided "as is" without express or + * implied warranty. + * + * OPEN SOFTWARE FOUNDATION DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL OPEN SOFTWARE FOUNDATIONN 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. + * + * M. Collins OSF + */ + +#include "Xlibint.h" +#include "Xlcint.h" + +void +XmbDrawText(dpy, d, gc, x, y, text_items, nitems) + Display *dpy; + Drawable d; + GC gc; + int x, y; + XmbTextItem *text_items; + int nitems; +{ + register XFontSet fs; + register XmbTextItem *p = text_items; + register int i = nitems; + register int esc; + + /* ignore leading items with no fontset */ + while (i && !p->font_set) { + i--; + p++; + } + + for (; --i >= 0; p++) { + if (p->font_set) + fs = p->font_set; + x += p->delta; + esc = (*fs->methods->mb_draw_string) (dpy, d, fs, gc, x, y, + p->chars, p->nchars); + if (!esc) + esc = fs->methods->mb_escapement (fs, p->chars, p->nchars); + x += esc; + } +} + +#if NeedFunctionPrototypes +void +XmbDrawString( + Display *dpy, + Drawable d, + XFontSet font_set, + GC gc, + int x, + int y, + _Xconst char *text, + int text_len) +#else +void +XmbDrawString(dpy, d, font_set, gc, x, y, text, text_len) + Display *dpy; + Drawable d; + XFontSet font_set; + GC gc; + int x, y; + char *text; + int text_len; +#endif +{ + (void)(*font_set->methods->mb_draw_string) (dpy, d, font_set, gc, x, y, + (char *)text, text_len); +} + + +#if NeedFunctionPrototypes +void +XmbDrawImageString( + Display *dpy, + Drawable d, + XFontSet font_set, + GC gc, + int x, + int y, + _Xconst char *text, + int text_len) +#else +void +XmbDrawImageString(dpy, d, font_set, gc, x, y, text, text_len) + Display *dpy; + Drawable d; + XFontSet font_set; + GC gc; + int x, y; + char *text; + int text_len; +#endif +{ + (*font_set->methods->mb_draw_image_string) (dpy, d, font_set, gc, x, y, + (char *)text, text_len); +} + +#if NeedFunctionPrototypes +int +XmbTextEscapement( + XFontSet font_set, + _Xconst char *text, + int text_len) +#else +int +XmbTextEscapement(font_set, text, text_len) + XFontSet font_set; + char *text; + int text_len; +#endif +{ + return (*font_set->methods->mb_escapement) (font_set, + (char *)text, text_len); +} + +#if NeedFunctionPrototypes +int +XmbTextExtents( + XFontSet font_set, + _Xconst char *text, + int text_len, + XRectangle *overall_ink_extents, + XRectangle *overall_logical_extents) +#else +int +XmbTextExtents(font_set, text, text_len, + overall_ink_extents, overall_logical_extents) + XFontSet font_set; + char *text; + int text_len; + XRectangle *overall_ink_extents; + XRectangle *overall_logical_extents; +#endif +{ + return (*font_set->methods->mb_extents) (font_set, + (char *)text, text_len, + overall_ink_extents, + overall_logical_extents); +} + +#if NeedFunctionPrototypes +Status +XmbTextPerCharExtents( + XFontSet font_set, + _Xconst char *text, + int text_len, + XRectangle *ink_extents_buffer, + XRectangle *logical_extents_buffer, + int buffer_size, + int *num_chars, + XRectangle *max_ink_extents, + XRectangle *max_logical_extents) +#else +Status +XmbTextPerCharExtents(font_set, text, text_len, + ink_extents_buffer, logical_extents_buffer, + buffer_size, num_chars, + max_ink_extents, max_logical_extents) + XFontSet font_set; + char *text; + int text_len; + XRectangle *ink_extents_buffer; + XRectangle *logical_extents_buffer; + int buffer_size; + int *num_chars; + XRectangle *max_ink_extents; + XRectangle *max_logical_extents; +#endif +{ + return (*font_set->methods->mb_extents_per_char) + (font_set, (char *)text, text_len, + ink_extents_buffer, logical_extents_buffer, + buffer_size, num_chars, max_ink_extents, max_logical_extents); +} diff --git a/src/xlibi18n/wcWrap.c b/src/xlibi18n/wcWrap.c new file mode 100644 index 00000000..621423d3 --- /dev/null +++ b/src/xlibi18n/wcWrap.c @@ -0,0 +1,218 @@ +/* $Xorg: wcWrap.c,v 1.4 2001/02/09 02:03:40 xorgcvs Exp $ */ +/* + +Copyright 1991, 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 1991 by the Open Software Foundation + * + * 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 Open Software Foundation + * not be used in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. Open Software + * Foundation makes no representations about the suitability of this + * software for any purpose. It is provided "as is" without express or + * implied warranty. + * + * OPEN SOFTWARE FOUNDATION DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL OPEN SOFTWARE FOUNDATIONN 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. + * + * M. Collins OSF + */ + +#include "Xlibint.h" +#include "Xlcint.h" + +void +XwcDrawText(dpy, d, gc, x, y, text_items, nitems) + Display *dpy; + Drawable d; + GC gc; + int x, y; + XwcTextItem *text_items; + int nitems; +{ + register XFontSet fs; + register XwcTextItem *p = text_items; + register int i = nitems; + register int esc; + + /* ignore leading items with no fontset */ + while (i && !p->font_set) { + i--; + p++; + } + + for (; --i >= 0; p++) { + if (p->font_set) + fs = p->font_set; + x += p->delta; + esc = (*fs->methods->wc_draw_string) (dpy, d, fs, gc, x, y, + p->chars, p->nchars); + if (!esc) + esc = fs->methods->wc_escapement (fs, p->chars, p->nchars); + x += esc; + } +} + +#if NeedFunctionPrototypes +void +XwcDrawString( + Display *dpy, + Drawable d, + XFontSet font_set, + GC gc, + int x, + int y, + _Xconst wchar_t *text, + int text_len) +#else +void +XwcDrawString(dpy, d, font_set, gc, x, y, text, text_len) + Display *dpy; + Drawable d; + XFontSet font_set; + GC gc; + int x, y; + wchar_t *text; + int text_len; +#endif +{ + (void)(*font_set->methods->wc_draw_string) (dpy, d, font_set, gc, x, y, + text, text_len); +} + +#if NeedFunctionPrototypes +void +XwcDrawImageString( + Display *dpy, + Drawable d, + XFontSet font_set, + GC gc, + int x, + int y, + _Xconst wchar_t *text, + int text_len) +#else +void +XwcDrawImageString(dpy, d, font_set, gc, x, y, text, text_len) + Display *dpy; + Drawable d; + XFontSet font_set; + GC gc; + int x, y; + wchar_t *text; + int text_len; +#endif +{ + (*font_set->methods->wc_draw_image_string) (dpy, d, font_set, gc, x, y, + text, text_len); +} + +#if NeedFunctionPrototypes +int +XwcTextEscapement( + XFontSet font_set, + _Xconst wchar_t *text, + int text_len) +#else +int +XwcTextEscapement(font_set, text, text_len) + XFontSet font_set; + wchar_t *text; + int text_len; +#endif +{ + return (*font_set->methods->wc_escapement) (font_set, text, text_len); +} + +#if NeedFunctionPrototypes +int +XwcTextExtents( + XFontSet font_set, + _Xconst wchar_t *text, + int text_len, + XRectangle *overall_ink_extents, + XRectangle *overall_logical_extents) +#else +int +XwcTextExtents(font_set, text, text_len, + overall_ink_extents, overall_logical_extents) + XFontSet font_set; + wchar_t *text; + int text_len; + XRectangle *overall_ink_extents; + XRectangle *overall_logical_extents; +#endif +{ + return (*font_set->methods->wc_extents) (font_set, text, text_len, + overall_ink_extents, + overall_logical_extents); +} + +#if NeedFunctionPrototypes +Status +XwcTextPerCharExtents( + XFontSet font_set, + _Xconst wchar_t *text, + int text_len, + XRectangle *ink_extents_buffer, + XRectangle *logical_extents_buffer, + int buffer_size, + int *num_chars, + XRectangle *max_ink_extents, + XRectangle *max_logical_extents) +#else +Status +XwcTextPerCharExtents(font_set, text, text_len, + ink_extents_buffer, logical_extents_buffer, + buffer_size, num_chars, + max_ink_extents, max_logical_extents) + XFontSet font_set; + wchar_t *text; + int text_len; + XRectangle *ink_extents_buffer; + XRectangle *logical_extents_buffer; + int buffer_size; + int *num_chars; + XRectangle *max_ink_extents; + XRectangle *max_logical_extents; +#endif +{ + return (*font_set->methods->wc_extents_per_char) + (font_set, text, text_len, + ink_extents_buffer, logical_extents_buffer, + buffer_size, num_chars, max_ink_extents, max_logical_extents); +} |