From f8612fcb21da2129083cd46d9d67b5cbc3435415 Mon Sep 17 00:00:00 2001 From: "(no author)" <(no author)@18797224-902f-48f8-a5cc-f745e15eee43> Date: Sat, 10 Jun 2006 00:21:06 +0000 Subject: [PATCH] This commit was manufactured by cvs2svn to create branch 'DOM_AGNOSTIC3_BRANCH'. git-svn-id: svn://10.0.0.236/branches/DOM_AGNOSTIC3_BRANCH@199651 18797224-902f-48f8-a5cc-f745e15eee43 --- .../public/nsIAccessibleEditableText.idl | 68 + .../public/nsIAccessibleHyperLink.idl | 76 + .../public/nsIAccessibleHyperText.idl | 54 + .../accessible/public/nsIAccessibleTable.idl | 82 + .../accessible/public/nsIAccessibleText.idl | 144 ++ .../accessible/public/nsIAccessibleValue.idl | 74 + mozilla/browser/app/apprunner-beos.rsrc | Bin 0 -> 10792 bytes .../locales/en-US/installer/appLocale.nsi | 3 + mozilla/db/sqlite3/src/os_beos.c | 1981 +++++++++++++++++ .../src/cairo-analysis-surface-private.h | 55 + .../cairo/cairo/src/cairo-analysis-surface.c | 259 +++ .../gfx/cairo/cairo/src/cairo-base85-stream.c | 130 ++ mozilla/gfx/cairo/cairo/src/cairo-operator.c | 119 + mozilla/gfx/cairo/cairo/src/cairo-pdf-test.h | 76 + .../src/cairo-scaled-font-subsets-private.h | 182 ++ .../cairo/src/cairo-scaled-font-subsets.c | 385 ++++ mozilla/gfx/thebes/src/nsUnicodeRange.cpp | 459 ++++ mozilla/gfx/thebes/src/nsUnicodeRange.h | 115 + .../html/tests/formctls/bugs/bug300474-1.html | 31 + .../html/tests/formctls/bugs/bug300474-2.html | 531 +++++ .../html/tests/formctls/bugs/bug53259-1.html | 40 + .../html/tests/formctls/bugs/bug53259-2.html | 24 + .../html/tests/formctls/bugs/bug53259-3.html | 46 + .../html/tests/formctls/bugs/bug7025-1.html | 27 + .../html/tests/formctls/bugs/bug7025-2.html | 78 + .../mailnews/base/public/nsIMsgTagService.idl | 72 + .../base/resources/content/newTagDialog.js | 90 + .../base/resources/content/newTagDialog.xul | 58 + .../resources/locale/en-US/newTagDialog.dtd | 38 + mozilla/mailnews/base/src/nsMsgTagService.cpp | 332 +++ mozilla/mailnews/base/src/nsMsgTagService.h | 76 + .../dns/public/nsIEffectiveTLDService.idl | 73 + .../netwerk/dns/src/nsEffectiveTLDService.cpp | 584 +++++ .../netwerk/dns/src/nsEffectiveTLDService.h | 53 + .../installer/windows/nsis/makensis.mk | 66 + 35 files changed, 6481 insertions(+) create mode 100644 mozilla/accessible/public/nsIAccessibleEditableText.idl create mode 100644 mozilla/accessible/public/nsIAccessibleHyperLink.idl create mode 100644 mozilla/accessible/public/nsIAccessibleHyperText.idl create mode 100644 mozilla/accessible/public/nsIAccessibleTable.idl create mode 100644 mozilla/accessible/public/nsIAccessibleText.idl create mode 100644 mozilla/accessible/public/nsIAccessibleValue.idl create mode 100644 mozilla/browser/app/apprunner-beos.rsrc create mode 100644 mozilla/browser/locales/en-US/installer/appLocale.nsi create mode 100644 mozilla/db/sqlite3/src/os_beos.c create mode 100644 mozilla/gfx/cairo/cairo/src/cairo-analysis-surface-private.h create mode 100644 mozilla/gfx/cairo/cairo/src/cairo-analysis-surface.c create mode 100644 mozilla/gfx/cairo/cairo/src/cairo-base85-stream.c create mode 100644 mozilla/gfx/cairo/cairo/src/cairo-operator.c create mode 100755 mozilla/gfx/cairo/cairo/src/cairo-pdf-test.h create mode 100644 mozilla/gfx/cairo/cairo/src/cairo-scaled-font-subsets-private.h create mode 100644 mozilla/gfx/cairo/cairo/src/cairo-scaled-font-subsets.c create mode 100644 mozilla/gfx/thebes/src/nsUnicodeRange.cpp create mode 100644 mozilla/gfx/thebes/src/nsUnicodeRange.h create mode 100644 mozilla/layout/html/tests/formctls/bugs/bug300474-1.html create mode 100644 mozilla/layout/html/tests/formctls/bugs/bug300474-2.html create mode 100644 mozilla/layout/html/tests/formctls/bugs/bug53259-1.html create mode 100644 mozilla/layout/html/tests/formctls/bugs/bug53259-2.html create mode 100644 mozilla/layout/html/tests/formctls/bugs/bug53259-3.html create mode 100644 mozilla/layout/html/tests/formctls/bugs/bug7025-1.html create mode 100644 mozilla/layout/html/tests/formctls/bugs/bug7025-2.html create mode 100755 mozilla/mailnews/base/public/nsIMsgTagService.idl create mode 100755 mozilla/mailnews/base/resources/content/newTagDialog.js create mode 100755 mozilla/mailnews/base/resources/content/newTagDialog.xul create mode 100755 mozilla/mailnews/base/resources/locale/en-US/newTagDialog.dtd create mode 100755 mozilla/mailnews/base/src/nsMsgTagService.cpp create mode 100755 mozilla/mailnews/base/src/nsMsgTagService.h create mode 100644 mozilla/netwerk/dns/public/nsIEffectiveTLDService.idl create mode 100644 mozilla/netwerk/dns/src/nsEffectiveTLDService.cpp create mode 100644 mozilla/netwerk/dns/src/nsEffectiveTLDService.h create mode 100755 mozilla/toolkit/mozapps/installer/windows/nsis/makensis.mk diff --git a/mozilla/accessible/public/nsIAccessibleEditableText.idl b/mozilla/accessible/public/nsIAccessibleEditableText.idl new file mode 100644 index 00000000000..00b6633ab78 --- /dev/null +++ b/mozilla/accessible/public/nsIAccessibleEditableText.idl @@ -0,0 +1,68 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is the Mozilla browser. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1999 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Paul Sandoz (paul.sandoz@sun.com) + * Bill Haneman (bill.haneman@sun.com) + * John Gaunt (jgaunt@netscape.com) + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsISupports.idl" + +[scriptable, uuid(91F0A56C-11BE-47C7-8D02-7C15E00C05F5)] +interface nsIAccessibleEditableText : nsISupports +{ + /** + * Set font styles, such as italic, bold... + */ + void setAttributes (in long startPos, in long endPos, + in nsISupports attributes); + void setTextContents (in AString text); + void insertText (in AString text, in long position); + void copyText (in long startPos, in long endPos); + void cutText (in long startPos, in long endPos); + void deleteText (in long startPos, in long endPos); + void pasteText (in long position); +}; + +/* + Assumptions: + + selectAttributes method takes an nsISupports parameter. + 'set' methods throw exception on failure. + 'wstring' inputs are potentially multibyte (UTF-16 for + instance); 'string' and UTF-8 may be a better choice. + +*/ diff --git a/mozilla/accessible/public/nsIAccessibleHyperLink.idl b/mozilla/accessible/public/nsIAccessibleHyperLink.idl new file mode 100644 index 00000000000..bde90c36f76 --- /dev/null +++ b/mozilla/accessible/public/nsIAccessibleHyperLink.idl @@ -0,0 +1,76 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is the Mozilla browser. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1999 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Bill Haneman (bill.haneman@sun.com) + * John Gaunt (jgaunt@netscape.com) + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsISupports.idl" + +interface nsIURI; +interface nsIAccessible; + +[scriptable, uuid(a492c7d6-1dd1-11b2-9bc0-80614884799a)] +interface nsIAccessibleHyperLink : nsISupports +{ + readonly attribute long anchors; + readonly attribute long startIndex; + readonly attribute long endIndex; + + nsIURI getURI (in long i); + + nsIAccessible getObject (in long i); + + boolean isValid (); + boolean isSelected (); +}; + +/* + Assumptions: + + The object associated with object or anchor index + is an nsIAccessible. + A URI can be represented by the nsIURI interface + (or nsIURL interface). + + Note that an object which supports nsIAccessibleHyperlink + does *not* generally implement nsIAccessible, unlike the + case of the other nsiAccessible* interfaces in this directory. + + Aaron: would the nsISupports return from + getObject be queryable for nsIURI and nsIURL directly? + +*/ diff --git a/mozilla/accessible/public/nsIAccessibleHyperText.idl b/mozilla/accessible/public/nsIAccessibleHyperText.idl new file mode 100644 index 00000000000..7803ecf10d9 --- /dev/null +++ b/mozilla/accessible/public/nsIAccessibleHyperText.idl @@ -0,0 +1,54 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is the Mozilla browser. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1999 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Bill Haneman (bill.haneman@sun.com) + * Paul Sandoz (paul.sandoz@sun.com) + * John Gaunt (jgaunt@netscape.com) + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsISupports.idl" +#include "nsIAccessibleHyperLink.idl" + +[scriptable, uuid(8f18d922-1dd2-11b2-82ea-829b78a44413)] +interface nsIAccessibleHyperText : nsISupports +{ + readonly attribute long links; + + nsIAccessibleHyperLink getLink (in long index); + + long getLinkIndex (in long charIndex); + long getSelectedLinkIndex (); +}; diff --git a/mozilla/accessible/public/nsIAccessibleTable.idl b/mozilla/accessible/public/nsIAccessibleTable.idl new file mode 100644 index 00000000000..91e54bde09f --- /dev/null +++ b/mozilla/accessible/public/nsIAccessibleTable.idl @@ -0,0 +1,82 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is the Mozilla browser. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1999 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Paul Sandoz (paul.sandoz@sun.com) + * Bill Haneman (bill.haneman@sun.com) + * John Gaunt (jgaunt@netscape.com) + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsISupports.idl" + +interface nsIAccessible; + +[scriptable, uuid(0A7E98A9-CA7D-42F0-BFE1-2CFC35256038)] +interface nsIAccessibleTable : nsISupports +{ + attribute nsIAccessible caption; + attribute AString summary; + readonly attribute long columns; + readonly attribute nsIAccessibleTable columnHeader; + readonly attribute long rows; + readonly attribute nsIAccessibleTable rowHeader; + + void getSelectedColumns (out unsigned long columnsSize, + [retval, array, size_is(columnsSize)] out long columns); + + void getSelectedRows (out unsigned long rowsSize, + [retval, array, size_is(rowsSize)] out long rows); + + /** + * gets a cell + */ + nsIAccessible cellRefAt (in long row, in long column); + + /** + * get an index + */ + long getIndexAt (in long row, in long column); + long getColumnAtIndex (in long index); + long getRowAtIndex (in long index); + long getColumnExtentAt (in long row, in long column); + long getRowExtentAt (in long row, in long column); + + AString getColumnDescription (in long column); + AString getRowDescription (in long row); + + boolean isColumnSelected (in long column); + boolean isRowSelected (in long row); + boolean isCellSelected (in long row, in long column); +}; diff --git a/mozilla/accessible/public/nsIAccessibleText.idl b/mozilla/accessible/public/nsIAccessibleText.idl new file mode 100644 index 00000000000..1b1335e51c7 --- /dev/null +++ b/mozilla/accessible/public/nsIAccessibleText.idl @@ -0,0 +1,144 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is the Mozilla browser. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1999 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Paul Sandoz (paul.sandoz@sun.com) + * Bill Haneman (bill.haneman@sun.com) + * John Gaunt (jgaunt@netscape.com) + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsISupports.idl" + +typedef long nsAccessibleTextBoundary; +typedef long nsAccessibleCoordType; + +[scriptable, uuid(E44D3FA6-9CB2-432A-8BDB-69D72B6ADA00)] +interface nsIAccessibleText : nsISupports +{ + const nsAccessibleTextBoundary BOUNDARY_CHAR = 0; + const nsAccessibleTextBoundary BOUNDARY_WORD_START = 1; + const nsAccessibleTextBoundary BOUNDARY_WORD_END = 2; + const nsAccessibleTextBoundary BOUNDARY_SENTENCE_START = 3; + const nsAccessibleTextBoundary BOUNDARY_SENTENCE_END = 4; + const nsAccessibleTextBoundary BOUNDARY_LINE_START = 5; + const nsAccessibleTextBoundary BOUNDARY_LINE_END = 6; + const nsAccessibleTextBoundary BOUNDARY_ATTRIBUTE_RANGE = 7; + + const nsAccessibleCoordType COORD_TYPE_SCREEN = 0; + const nsAccessibleCoordType COORD_TYPE_WINDOW = 1; + + attribute long caretOffset; + + readonly attribute long characterCount; + readonly attribute long selectionCount; + + /** + * String methods may need to return multibyte-encoded strings, + * since some locales can't be encoded using 16-bit chars. + * So the methods below might return UTF-16 strings, or they could + * return "string" values which are UTF-8. + */ + AString getText (in long startOffset, in long endOffset); + + AString getTextAfterOffset (in long offset, + in nsAccessibleTextBoundary boundaryType, + out long startOffset, + out long endOffset); + + AString getTextAtOffset (in long offset, + in nsAccessibleTextBoundary boundaryType, + out long startOffset, + out long endOffset); + + AString getTextBeforeOffset (in long offset, + in nsAccessibleTextBoundary boundaryType, + out long startOffset, + out long endOffset); + + /** + * It would be better to return an unsigned long here, + * to allow unicode chars > 16 bits + */ + wchar getCharacterAtOffset (in long offset); + + nsISupports getAttributeRange (in long offset, + out long rangeStartOffset, + out long rangeEndOffset); + + void getCharacterExtents (in long offset, + out long x, + out long y, + out long width, + out long height, + in nsAccessibleCoordType coordType); + + long getOffsetAtPoint (in long x, in long y, + in nsAccessibleCoordType coordType); + + void getSelectionBounds (in long selectionNum, + out long startOffset, + out long endOffset); + + void setSelectionBounds (in long selectionNum, + in long startOffset, + in long endOffset); + + void addSelection (in long startOffset, in long endOffset); + + void removeSelection (in long selectionNum); +}; + +/* + Assumptions: + + Using wstring (UCS2) instead of string encoded in UTF-8. + Multibyte encodings (or at least potentially multi-byte + encodings) would be preferred for the reasons cited above. + + The following methods will throw an exception on failure + (since not every text component will allow every operation): + setSelectionBounds, addSelection, removeSelection, setCaretOffset. + + getRangeAttributes defined to return an nsISupports + interface instead of a pango specific data structure. + It may be that some other return type is more appropriate + for mozilla text attributes. + + we assume that all text components support the idea of + a caret offset, whether visible or "virtual". If this + isn't the case, caretOffset can be made readonly and + a setCaretOffset method provided which throws an exception + on failure (as with *selection methods above). +*/ diff --git a/mozilla/accessible/public/nsIAccessibleValue.idl b/mozilla/accessible/public/nsIAccessibleValue.idl new file mode 100644 index 00000000000..8dbd9d47e5e --- /dev/null +++ b/mozilla/accessible/public/nsIAccessibleValue.idl @@ -0,0 +1,74 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is the Mozilla browser. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1999 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * John Gaunt (jgaunt@netscape.com) + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsISupports.idl" + +[scriptable, uuid(F4ABBC2F-0F28-47DC-A9E9-F7A1719AB2BE)] +interface nsIAccessibleValue : nsISupports +{ + readonly attribute double maximumValue; + readonly attribute double minimumValue; + readonly attribute double currentValue; + + /** + * We want to be able to return a success condition of the value + * getting set. ie if the value is not within the interval of + * minimumValue-maximumValue + */ + boolean setCurrentValue (in double value); +}; + +/* + Assumptions: + + The attribute currentValue will throw an exception + if it cannot be set i.e. if the value is not a + member of the interval. + This may not be the 'desired' behaviour given gObject + equivalent. Thus it could be changed to be: + + readonly attribute double currentValue; + boolean setCurrentValue (double long value); + + GValue can represent many basic types. + Since this interface is designed to represent + an interval and a member of double should + cover the cases of char int and float. + +*/ diff --git a/mozilla/browser/app/apprunner-beos.rsrc b/mozilla/browser/app/apprunner-beos.rsrc new file mode 100644 index 0000000000000000000000000000000000000000..145e9ca36dfca8072be0b28e2c1c6c93b6dff813 GIT binary patch literal 10792 zcmeHtbyQSs+wTxcx6%y`(karQ3?(TcH86B{w-VCbB?2;}NJ&U34Fb~A4bmXpaQ3Lr z_k8bp*Llx6XRYtQ=UQvezOViJUBBzPult@gv)A6LY9J5@Um0>2I6)8xV(|ZAh*%I1 zyMgjs!vg8|7;*U)FvRu$iLnSX2(%6eBlO>+fk3Fg(}2o>@n23k7BB|tL0CC92t@yT z2pR^)5B^*~#Q}k&DE3_0jM3#T_fA{*IKK#>%fA+vXd*Giv@c*_45dHeU8W;?o znep@Uo0$QF|D6m5&(8S45)zye5@3EaV5a|#0l+{gKyY#baKG~6!T&~p!@*2Iw4WcY z-yhr$^K9a80vvvaX?AuNce2qXS+P7#O6RR}D*m0hR!pnVBuV z`ilU-K0Z*Wk8TGhP#{79<_DXdgI-?+{Zjba0SC<2*SGhMA0ixKKnl#&tJQzSJ9>M^ z|6%|oG_9^81O|VFBjVv5fdRj9M2R!StE*=K-V5aaCGYF2ON4-dHXs@~TYh%-8~+3Q zq~-w-fCK0(&}H=BxbB~D#2hdX!hS$6W@r6o{={=2a5%iTw->YgH~xz-Gh5zt)&%5d z|Ahna(61i<5&$y+mIrM@wD1=WOsxZccLuOoAoVN)Mu7qb;2i7-d7#O@@WJncc~EHB z%nSfOEdPUV{T4uE0eX;{3J(InhYyic|KKI;zXSky3lQn(n41Mq6hLS~7y4@f*nbHi z`Uez=HaiPMGv^IK&#rZUuP`70hy%DU9EAzkg#cUvXkSnK4hLp{ARusH2~nAtkcaY8 zp-sU4_-lgz0)G)w{}`}#XMe$nDFVj!mj)c3+H?lMdBEiV*e?QtgqQ$4HMOa!37YyB zh&cZj;a9DQB>ycMLEuD0|FYlP0dehLZR>ABNAJHve|aScPH%6?U;h8#IXar~HjEIF zAS~ea12$oF)W_e|)5Yz-MLi7gXCEx-(J^ZW~@bmJ@{ff&0#w_$K90zD` z5Ww+8hxq~Dfa2R;-&APo*YC4{8?<^>cFW!IOJR0w5V|^13>3tPSP>r|Umv}*JPg1` z=R_=Js&A@Z@pr(zy~R2Ky3f|pJ2>{s1wO`5QBY8Rdxj1UHkQVQE|&IooF43Mb|xH( z_Fk4YHiqodmQJQ-_8uVar^?bu`sf6RfA`yH`XD4ERdqE<#4Q2hKH!dvr-P|8Cg8Z3 zdbn^}xY*i&a9>da{=X|fHRaGyRp2nQv@u0Q14acL|7V_y0|>Yi;R9oC|3^Iw7l7zu z@8k&r(flVp1kd^R%?s^+;@KKn+PK(*M2a1S|6^V|Q+H>Oi?auy1zK~Xw#F(i#=Ozd9nJg|I}Xp z$nr1)_HzFx&9@tei{qDmu6}&YzMe;8Z+%xJ^b{?HGavM&4e3mCuCaxaaW=J?CFX=om2vxmdc?&f)hy(PXF zw$OV2P;H7P=V#wQ3O_C(+vqucy=Gz0|xRKqSN|fQ$D8`PK`d-Cr*c3oYW#7 zX9w%yR#~^_2Nwqvy|u}wnKRx$e>RxgH;Z~XR!@sgU9p&4%~KAkeU@Pu3gRegDQ?tw zGa?yYUu%dy={kg?y($*`TG|&lwvjw5Y0*&l= zPdq=>6|ztB31rlp%G{Vc`^b0sw%?j|?JH62l`gxnYjB5 zt6xF*>4>9z%v1|%gtQF{2}!l7SL?%#vza&wD%cSpj!>HSRuP#^Xmx=P_bDIti!Hm! zxK9OTZ$&?Q)m*ZRag@z-P2YCyy}jAprXXsbq_mZzWQY=Bk|z-tn3YB2c&;UtHKh=X5!!exSu+>W=N<2F!5ZubXU&(yquxIh#^Vw*+Xwh)2$gLBCmBmZIgSp*e1wP$HKy>wuSElmKO&b z2%F!9H&Dj}DdG6fNtMZojZh>$I^eO=keMkc+h}%o4EZd_(ztriZ^bZu9f^Ba$L0s{$Y&}ZAf4 zT{&xYA}{EPjvJnlk~7Y=F)V-PfvZiXEcUxPju)v?dzyK9G7Z#!tTvrvcJ7`}-bm)L z+9+Kz^gcIRA{#ZH>ZUcdvnm)OC3R#U(3|V?kZGx%bn}6`|dLKNo-Smq{&)iWq3?XY0QM|Nk_;xw)5n$fEV!$Y1vba}I8 zWF#@D^g})Mj*iMkGe5nN0u>E~E6*`b)c9qq*E)MW!+_Q&m_RXs@?u^QG^muUE>UI? zo7jWbWI2d%T1cG?UB~WYo`Uh}Qmh$WO6?_Iaq|hu$m{VKk0x_8HdjSY8PbqV!c-ow z;o|zC5GmalUwV1uR~lj+q(=!{7ky*q#F4(XqNc+9yg8=eJht!=C8K*$$(0XvHk8sX zw6W}2%Z8S7XY$fo%@oGsx-^TQrD3#0y0%F}c%Ml|ty(8`)D+t;;`9-1CDe%2IKNm6 z)0dnDJwdm@f0L&WMHxcxbxs)ABI08DQUgFH<{`$Z4q8Yl_{$&e<4vfb-JH_Pkq(0jlTwNe^eq7W3Vvp!2(@;zI*Mgd=< zC8(8xhpE-3TpC9j3+Ko8o$HEMbJDxyhdNTFsRo|59WPs*c*M)257`unG><$V%^OaS ze;rxbpPxvk;5A-#73QXK9Zvnm#a?XBHRs0j;1G&QX}KFyyhK@p_vxE)^+A1ijyac9 zB+m;i>8WCL)~U$p?-Gwx%nj?lxR|&xRq}YUoJN*D91~o!EP>o7_s7)0!JvI(Q@Crc zXKHTC=t88&mBh54YT`DG3oVTvDR`D)d!H{3y2#DUgk)1d6y#OZ&b~n|ZH#lvFKqC%NO8-TtTw&F5DfUhfjW(*5)qcg6 zd8T5P(9(8I8?1I~)*xw@99EIeJgb#QQtB)0dZUzQX79{N{>pAdGRJVlA9@AQ$Db}ez2yiS8c;zrn}Jm z%U2SySi)SSC*Vi@j`mjzKCzW!fi-4q7a?FH#=A&i&?4drVw1T)apmPRI1zlKCh~enxX% znV!~WmL=gMKEY4-6Syk3{bNbC4(E);QPjk>rHMLec5yq3<;jJ&6UpvT$EoZaqf2%? zedz6DW-1@>SBiyYQ1^HPQr+MoNk=VFL+aO699HHf^oR`7Or^*!G{ zwlzFH>YvAqpt;Vbu?--Lul933de>Q52glX9=oFdCgH#c&V+C>+CUnjM^p%S5oBRH& zyd`$9KCc5tvFDp#SW+?EG&)YTQtKx-8ak`S$6=yZ4Q__M*GWM>9*ri|ZPsd*IvMnD zg{&Vk6|_?@=}Asu-Uz6NG#A2PjNsG=}m_a>5}5EXcEUS)EC zyrHOip+}2_N~?jH_o(vq>u==wuM_c2Qlm<=NbdBBCUG7uV3#GGgGLDHF~Gha?4?mz zruSLrC*8qD?D>b~*p4N<+AE>lgI?PMh1&xYcxy1$I2_3^rn+^y8U z%S#(&vvI#iYyDPMN1`q3fyiQ%A)(i-FdM`Ja@H*u*)H*Z1$jCw)1x1GiWj@30#6b& zg+s?hT!Z`QC>I(mv*+A>g71=zT^@8udF`AfN&0@gfX6`6fgA^ZZwOV7bo1%xbe00m zaqCf@1W(*-!gWqS7V4OveP2RWY*TZi6;FDEHt6G|n?-;tA;;G0%rtGZ zAu%u-fP+Oz4}!Evj`Ggn%@}V)24B+<6rc=Hh^OEy(X*hfaNs9B!HK;q&%aJM{ow=i zcnyXOf!Yv7D2!5V>Rl6oYA(vztB^h?%CGmIlRQBmMo&LC;)qIT2I;@jTrH|?vPzdv z-TcZB%t<(FaR*nwHuUj;@F#swF#Lyr0-1E#P*@eUE>hExhqy+ zo`;!xH$SA)H&(@}mT^Up49<;1?oVaVWG8XfIz} z^pCLFEcX7iCWu$r2K6H0kVPr#_`4E=gJCOavdIMy-m=%KS)pBtNh#fdMbdF4_2`k)54Y>JL?(8N--xd>1GV9ZvgBW!`4}mc zej<7;(SHYgpS>>E*<&j7h6Iasiv5F~nJ$|_?)fwqcUfSV3Kp}pf0#*^j|2ySK`x!K zqFK%YL`qHGY<*W^pKET!dsF0GrSQ~w@%;@D_wxw%Xc-XI?&BEIoxo?>_0Z+pP zHO;Qn!)uqi1VuZbWln!jBqY1_#w$!c=y_w)VsFclQx%f+)X(L7_83Y-c}BLSV6Cm^Z!LU^dphXwGARpb{fmptdrPKI z+wWOD8)nT#UqBYrVU%)hNOyG4|65B}3R0 zRx4`0`qUT82SWI_(mck_X|LHlPiov4hbb}n6*o@5S4b$wSPl}St zl%it@n-PbQ_>TxnDiuTotjdsyikii9mO=X1yM`G0F?3id)}N})Jz^Hx!ADC#%_~xn z5W~?%=27=gEZ8tbCE?SXn&1csQLU}>n)-G^UTUhD8v=6A$qsoHD$Q0nXUf+9sko-R zt2-kGZ!2j!u+n+(Mn%dA?c_bJ*5OJv!{VzjyHm6Sx|d&qr=zYv;cUi=FUV!ukK6HE zxf;|GoS%EMWOa-*Ob5IjiW{_y!8$rUWZXuz;WH;d{U(!`NqI0y{~}MW(2*dP)gZP= zFrJPi%2ZI196f9K(i2nMsD~IFgwj>r$UyatnP=sF%14^B!}pK8{g_@wKBjaGk%ZN& zENv2#eb8V^sDv!YkK3TJb)89_Zy3p1e+<+upyIN#@n%j1d%cwsj4k^5oj(ljs>{fhQm~t3D5liD>9}@12nK5}A}uAAB%(nB=|UXr5f^x2|J;zXG;- z5&1|q_x{E=Qs3vMxPqIVDL)_NbQkW?DLgd*?-iw9<%FY#p1x*w5+F_8H-u>_AGI7s zCoW}$n=d91lU4Ta6D6d37L-ewNg3^e89p;e^Qw%>$+37-t4qiRVhagpAZ=~0eE6g; zf?)z~|G+#D(e#2z{}xj#-dH@sCoO`4-R<#*@or5hE6j{b@COSFm#nhlYYG@^DZKdv zl`_DY2G$%PUvjpW5b^W^@5lL(f54h};Y}Cblg`OO12ykW9%B9-8%x43RbNOc%@Ty!Lfn+~`F6ZH_nJ32;8@xIF{=x}oLuT*9c z$K~sgxK>v)4mM+AYxfw4EoWSgk2=p~=1lSv_zO^7<30g1AXOuORQoZ5Wbe#GsttY0 z2(f7Wxe$kZ(w-_O}p$8TH`0r!?F(96Czy;f9of-e|I2SLDYQ#BIt#DKqZmiJ_k!xq)vcOCh1<$!QkTWi%myOQ zxS-Rhm4d0e2Ie7c~iFiQZo!FcA!Lx4;3fX^}{XBuDL-Gwn3L;WJOC{Wyl( z*(RgiL1Y&HCZ?Udb04hQz^-fLX>7;Y80=e;&z=IuZ_6IHo|9TJ%-74;EkO0{fe1~C zHCT9hRtN9B;OJxMV9}WGBh<7`VOc9$aP8TAM^Jp`sc~~ye8uUkF*j-UB!SnNkosbYkQfW2a{^!E+nW`)aPHh488WX ze6@Y+6eDOsYEUSG`|is(Mv`93drm(|+)66m2D1^5XwDBGIz4x=d;dcvWAxD~a_6Q$ zEox^L2e~c-E^Epqih>;*SFcRvr(%%zAeWZWksalI)E6Fi&>={@zm zGb0Wip7AuzUqRfxBh2}PL$-+pRca|36P&#rXcS)Tp7j4XhthyhE>NPr6>OogcR4(M z&HX?!=u5%9_{+t}BFj2~s5>5`W{mX|`#vIX_X$fWUB@Fp{HuCH{A2~QN|kGk+v-Xc z;pNLHylk=7ZXN|Ep*LP)N-U&ev=6jG%WcfSnhNcW)W$64i;AmG97f_a8J7lP5rL4G zuM^7@+P>u9s02ZEu|*fv_tG7J%?QFBONEFW?g(3Z`xn=GJ6v1VJF8pRqG5!$HaU&46W zZt2*5=RL;iq+9x#C*Ao?%Sz_wg>t*E-i~@zk(qXE3=L-Y(+1Kcytuw?c9)PO+BRfw zb4&#{oEYIOm-ZR_oX9o}M++RG&dlP+jV-)KbN3UO5*!AJy_O5#BQX&lcqZ=mmiE$9 z?9tjDk%_ps&!*BGL-))M-xylqo;cCRZ+{YQi2C>9aoebYpOtUh zk%>8mw!q^QbsK##tX&&1Sim?z8|MzOHrXNpig~1r_reogyU!yH-DInfzbUZPu2y6! ze+kdu4r=9p_Bh^hBpHwA3z?AGr>qbh-LG8~I{dl(N!KO?SuRB1sdGL;Yf1YLtfKUF zymf*@UbBa3mA;k84$3-(f*i|TTWZS2nD@e^UhX)j^a(|*b<;Em-^$=K`?pWkbJ<(UX^&l^r; ze6l*cE2sWcR&qH2Uy^)tZoslVIDVC4XHa%y@v~Q0 zpaQ!=*>hQB)>1imm})|a;-$Y{Q5;@%cCC9vr+sEPBMshuLj30&SnnWvnzV|_6T~Zo zhyxGwR7zP*=!uF7Oj_ZIjM}f4{1DGCm6Rpr5Kr8Yfdl_HNkK?W9Rib+R95<%B`K$f zU?JX={KHcGcb1x>oFXC_;zdWCzZ0s-$^4g)jEveZ%ALQ3q~#Q(VCvc`Qhyf()Z_&a V5HD^1mF~sArz0{j`t{iKe*y5JiFE(~ literal 0 HcmV?d00001 diff --git a/mozilla/browser/locales/en-US/installer/appLocale.nsi b/mozilla/browser/locales/en-US/installer/appLocale.nsi new file mode 100644 index 00000000000..62356d89f48 --- /dev/null +++ b/mozilla/browser/locales/en-US/installer/appLocale.nsi @@ -0,0 +1,3 @@ +; uncomment the define below if your product and locale +; can do the uninstall survey. see SURVEY_TEXT and SurveyURL +!define DO_UNINSTALL_SURVEY diff --git a/mozilla/db/sqlite3/src/os_beos.c b/mozilla/db/sqlite3/src/os_beos.c new file mode 100644 index 00000000000..f7be2cc35e0 --- /dev/null +++ b/mozilla/db/sqlite3/src/os_beos.c @@ -0,0 +1,1981 @@ +/* +** 2004 May 22 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** This file contains code that is specific to BeOS systems. +** Code is derived from sqlite3 os_unix.c, with BeOS modifications by DeadYak +** and mmu_man of the Haiku OS team. +*/ +#include "sqliteInt.h" +#include "os.h" +#if OS_BEOS /* This file is used on BeOS and derivatives only */ + +/* +** These #defines should enable >2GB file support on Posix if the +** underlying operating system supports it. If the OS lacks +** large file support, these should be no-ops. +** +** Large file support can be disabled using the -DSQLITE_DISABLE_LFS switch +** on the compiler command line. This is necessary if you are compiling +** on a recent machine (ex: RedHat 7.2) but you want your code to work +** on an older machine (ex: RedHat 6.0). If you compile on RedHat 7.2 +** without this option, LFS is enable. But LFS does not exist in the kernel +** in RedHat 6.0, so the code won't work. Hence, for maximum binary +** portability you should omit LFS. +*/ +#ifndef SQLITE_DISABLE_LFS +# define _LARGE_FILE 1 +# ifndef _FILE_OFFSET_BITS +# define _FILE_OFFSET_BITS 64 +# endif +# define _LARGEFILE_SOURCE 1 +#endif + +/* +** standard include files. +*/ +#include +#include +#include +#include +#include +#include +#include +#include + +/* +** If we are to be thread-safe, include the BeOS os header that includes bthreads +** and define the SQLITE_BEOS_THREADS macro. +*/ +#if defined(THREADSAFE) && THREADSAFE +# include +# define SQLITE_BEOS_THREADS 1 +#endif + +/* +** Default permissions when creating a new file +*/ +#ifndef SQLITE_DEFAULT_FILE_PERMISSIONS +# define SQLITE_DEFAULT_FILE_PERMISSIONS 0644 +#endif + + + +/* +** For sqlite, BeOS uses the same file structure as Unix. +** The unixFile structure is subclass of OsFile specific for the unix +** portability layer. +*/ +typedef struct unixFile unixFile; +struct unixFile { + IoMethod const *pMethod; /* Always the first entry */ + struct openCnt *pOpen; /* Info about all open fd's on this inode */ + struct lockInfo *pLock; /* Info about locks on this inode */ + int h; /* The file descriptor */ + unsigned char locktype; /* The type of lock held on this fd */ + unsigned char isOpen; /* True if needs to be closed */ + unsigned char fullSync; /* Use F_FULLSYNC if available */ + int dirfd; /* File descriptor for the directory */ + i64 offset; /* Seek offset */ +#ifdef SQLITE_BEOS_THREADS + thread_id tid; /* The thread that "owns" this OsFile */ +#endif +}; + +/* +** Provide the ability to override some OS-layer functions during +** testing. This is used to simulate OS crashes to verify that +** commits are atomic even in the event of an OS crash. +*/ +#ifdef SQLITE_CRASH_TEST + extern int sqlite3CrashTestEnable; + extern int sqlite3CrashOpenReadWrite(const char*, OsFile**, int*); + extern int sqlite3CrashOpenExclusive(const char*, OsFile**, int); + extern int sqlite3CrashOpenReadOnly(const char*, OsFile**, int); +# define CRASH_TEST_OVERRIDE(X,A,B,C) \ + if(sqlite3CrashTestEnable){ return X(A,B,C); } +#else +# define CRASH_TEST_OVERRIDE(X,A,B,C) /* no-op */ +#endif + + +/* +** Include code that is common to all os_*.c files +*/ +#include "os_common.h" + +/* +** Do not include any of the File I/O interface procedures if the +** SQLITE_OMIT_DISKIO macro is defined (indicating that the database +** will be in-memory only) +*/ +#ifndef SQLITE_OMIT_DISKIO + + +/* +** Define various macros that are missing from some systems. +*/ +#ifndef O_LARGEFILE +# define O_LARGEFILE 0 +#endif +#ifdef SQLITE_DISABLE_LFS +# undef O_LARGEFILE +# define O_LARGEFILE 0 +#endif +#ifndef O_NOFOLLOW +# define O_NOFOLLOW 0 +#endif +#ifndef O_BINARY +# define O_BINARY 0 +#endif + +/* +** The DJGPP compiler environment looks mostly like Unix, but it +** lacks the fcntl() system call. So redefine fcntl() to be something +** that always succeeds. This means that locking does not occur under +** DJGPP. But it's DOS - what did you expect? +*/ +#ifdef __DJGPP__ +# define fcntl(A,B,C) 0 +#endif + +/* +** The threadid macro resolves to the thread-id or to 0. Used for +** testing and debugging only. +*/ +#ifdef SQLITE_BEOS_THREADS +#define threadid find_thread(NULL) +#else +#define threadid 0 +#endif + +/* +** Set or check the OsFile.tid field. This field is set when an OsFile +** is first opened. All subsequent uses of the OsFile verify that the +** same thread is operating on the OsFile. Some operating systems do +** not allow locks to be overridden by other threads and that restriction +** means that sqlite3* database handles cannot be moved from one thread +** to another. This logic makes sure a user does not try to do that +** by mistake. +** +** Version 3.3.1 (2006-01-15): OsFiles can be moved from one thread to +** another as long as we are running on a system that supports threads +** overriding each others locks (which now the most common behavior) +** or if no locks are held. But the OsFile.pLock field needs to be +** recomputed because its key includes the thread-id. See the +** transferOwnership() function below for additional information +** +** This code is BeOS-specific and differs from Unix. +*/ +#if defined(SQLITE_BEOS_THREADS) +# define SET_THREADID(X) (X)->tid = find_thread(NULL) +# define CHECK_THREADID(X) (threadsOverrideEachOthersLocks==0 && \ + !((X)->tid == find_thread(NULL))) +#else +# define SET_THREADID(X) +# define CHECK_THREADID(X) 0 +#endif + +/* +** Here is the dirt on POSIX advisory locks: ANSI STD 1003.1 (1996) +** section 6.5.2.2 lines 483 through 490 specify that when a process +** sets or clears a lock, that operation overrides any prior locks set +** by the same process. It does not explicitly say so, but this implies +** that it overrides locks set by the same process using a different +** file descriptor. Consider this test case: +** +** int fd1 = open("./file1", O_RDWR|O_CREAT, 0644); +** int fd2 = open("./file2", O_RDWR|O_CREAT, 0644); +** +** Suppose ./file1 and ./file2 are really the same file (because +** one is a hard or symbolic link to the other) then if you set +** an exclusive lock on fd1, then try to get an exclusive lock +** on fd2, it works. I would have expected the second lock to +** fail since there was already a lock on the file due to fd1. +** But not so. Since both locks came from the same process, the +** second overrides the first, even though they were on different +** file descriptors opened on different file names. +** +** Bummer. If you ask me, this is broken. Badly broken. It means +** that we cannot use POSIX locks to synchronize file access among +** competing threads of the same process. POSIX locks will work fine +** to synchronize access for threads in separate processes, but not +** threads within the same process. +** +** To work around the problem, SQLite has to manage file locks internally +** on its own. Whenever a new database is opened, we have to find the +** specific inode of the database file (the inode is determined by the +** st_dev and st_ino fields of the stat structure that fstat() fills in) +** and check for locks already existing on that inode. When locks are +** created or removed, we have to look at our own internal record of the +** locks to see if another thread has previously set a lock on that same +** inode. +** +** The OsFile structure for POSIX is no longer just an integer file +** descriptor. It is now a structure that holds the integer file +** descriptor and a pointer to a structure that describes the internal +** locks on the corresponding inode. There is one locking structure +** per inode, so if the same inode is opened twice, both OsFile structures +** point to the same locking structure. The locking structure keeps +** a reference count (so we will know when to delete it) and a "cnt" +** field that tells us its internal lock status. cnt==0 means the +** file is unlocked. cnt==-1 means the file has an exclusive lock. +** cnt>0 means there are cnt shared locks on the file. +** +** Any attempt to lock or unlock a file first checks the locking +** structure. The fcntl() system call is only invoked to set a +** POSIX lock if the internal lock structure transitions between +** a locked and an unlocked state. +** +** 2004-Jan-11: +** More recent discoveries about POSIX advisory locks. (The more +** I discover, the more I realize the a POSIX advisory locks are +** an abomination.) +** +** If you close a file descriptor that points to a file that has locks, +** all locks on that file that are owned by the current process are +** released. To work around this problem, each OsFile structure contains +** a pointer to an openCnt structure. There is one openCnt structure +** per open inode, which means that multiple OsFiles can point to a single +** openCnt. When an attempt is made to close an OsFile, if there are +** other OsFiles open on the same inode that are holding locks, the call +** to close() the file descriptor is deferred until all of the locks clear. +** The openCnt structure keeps a list of file descriptors that need to +** be closed and that list is walked (and cleared) when the last lock +** clears. +** +** First, under Linux threads, because each thread has a separate +** process ID, lock operations in one thread do not override locks +** to the same file in other threads. Linux threads behave like +** separate processes in this respect. But, if you close a file +** descriptor in linux threads, all locks are cleared, even locks +** on other threads and even though the other threads have different +** process IDs. Linux threads is inconsistent in this respect. +** (I'm beginning to think that linux threads is an abomination too.) +** The consequence of this all is that the hash table for the lockInfo +** structure has to include the process id as part of its key because +** locks in different threads are treated as distinct. But the +** openCnt structure should not include the process id in its +** key because close() clears lock on all threads, not just the current +** thread. Were it not for this goofiness in linux threads, we could +** combine the lockInfo and openCnt structures into a single structure. +** +** 2004-Jun-28: +** On some versions of linux, threads can override each others locks. +** On others not. Sometimes you can change the behavior on the same +** system by setting the LD_ASSUME_KERNEL environment variable. The +** POSIX standard is silent as to which behavior is correct, as far +** as I can tell, so other versions of unix might show the same +** inconsistency. There is no little doubt in my mind that posix +** advisory locks and linux threads are profoundly broken. +** +** To work around the inconsistencies, we have to test at runtime +** whether or not threads can override each others locks. This test +** is run once, the first time any lock is attempted. A static +** variable is set to record the results of this test for future +** use. +*/ + +/* +** An instance of the following structure serves as the key used +** to locate a particular lockInfo structure given its inode. +** +** If threads cannot override each others locks, then we set the +** lockKey.tid field to the thread ID. If threads can override +** each others locks then tid is always set to zero. tid is omitted +** if we compile without threading support. +*/ +struct lockKey { + dev_t dev; /* Device number */ + ino_t ino; /* Inode number */ +#ifdef SQLITE_BEOS_THREADS + thread_id tid; /* Thread ID or zero if threads can override each other */ +#endif +}; + +/* +** An instance of the following structure is allocated for each open +** inode on each thread with a different process ID. (Threads have +** different process IDs on linux, but not on most other unixes.) +** +** A single inode can have multiple file descriptors, so each OsFile +** structure contains a pointer to an instance of this object and this +** object keeps a count of the number of OsFiles pointing to it. +*/ +struct lockInfo { + struct lockKey key; /* The lookup key */ + int cnt; /* Number of SHARED locks held */ + int locktype; /* One of SHARED_LOCK, RESERVED_LOCK etc. */ + int nRef; /* Number of pointers to this structure */ +}; + +/* +** An instance of the following structure serves as the key used +** to locate a particular openCnt structure given its inode. This +** is the same as the lockKey except that the thread ID is omitted. +*/ +struct openKey { + dev_t dev; /* Device number */ + ino_t ino; /* Inode number */ +}; + +/* +** An instance of the following structure is allocated for each open +** inode. This structure keeps track of the number of locks on that +** inode. If a close is attempted against an inode that is holding +** locks, the close is deferred until all locks clear by adding the +** file descriptor to be closed to the pending list. +*/ +struct openCnt { + struct openKey key; /* The lookup key */ + int nRef; /* Number of pointers to this structure */ + int nLock; /* Number of outstanding locks */ + int nPending; /* Number of pending close() operations */ + int *aPending; /* Malloced space holding fd's awaiting a close() */ +}; + +/* +** These hash tables map inodes and file descriptors (really, lockKey and +** openKey structures) into lockInfo and openCnt structures. Access to +** these hash tables must be protected by a mutex. +*/ +static Hash lockHash = {SQLITE_HASH_BINARY, 0, 0, 0, + sqlite3ThreadSafeMalloc, sqlite3ThreadSafeFree, 0, 0}; +static Hash openHash = {SQLITE_HASH_BINARY, 0, 0, 0, + sqlite3ThreadSafeMalloc, sqlite3ThreadSafeFree, 0, 0}; + +#ifdef SQLITE_BEOS_THREADS +/* +** This variable records whether or not threads can override each others +** locks. +** +** 0: No. Threads cannot override each others locks. +** 1: Yes. Threads can override each others locks. +** -1: We don't know yet. +** +** On some systems, we know at compile-time if threads can override each +** others locks. On those systems, the SQLITE_THREAD_OVERRIDE_LOCK macro +** will be set appropriately. On other systems, we have to check at +** runtime. On these latter systems, SQLTIE_THREAD_OVERRIDE_LOCK is +** undefined. +** +** This variable normally has file scope only. But during testing, we make +** it a global so that the test code can change its value in order to verify +** that the right stuff happens in either case. +*/ +#ifndef SQLITE_THREAD_OVERRIDE_LOCK +# define SQLITE_THREAD_OVERRIDE_LOCK 1 +#endif +#ifdef SQLITE_TEST +int threadsOverrideEachOthersLocks = SQLITE_THREAD_OVERRIDE_LOCK; +#else +static int threadsOverrideEachOthersLocks = SQLITE_THREAD_OVERRIDE_LOCK; +#endif + +/* +** This structure holds information passed into individual test +** threads by the testThreadLockingBehavior() routine. +*/ +struct threadTestData { + int fd; /* File to be locked */ + struct flock lock; /* The locking operation */ + int result; /* Result of the locking operation */ +}; + +#ifdef SQLITE_LOCK_TRACE +/* +** Print out information about all locking operations. +** +** This routine is used for troubleshooting locks on multithreaded +** platforms. Enable by compiling with the -DSQLITE_LOCK_TRACE +** command-line option on the compiler. This code is normally +** turned off. +*/ +static int lockTrace(int fd, int op, struct flock *p){ + char *zOpName, *zType; + int s; + int savedErrno; + if( op==F_GETLK ){ + zOpName = "GETLK"; + }else if( op==F_SETLK ){ + zOpName = "SETLK"; + }else{ + s = fcntl(fd, op, p); + sqlite3DebugPrintf("fcntl unknown %d %d %d\n", fd, op, s); + return s; + } + if( p->l_type==F_RDLCK ){ + zType = "RDLCK"; + }else if( p->l_type==F_WRLCK ){ + zType = "WRLCK"; + }else if( p->l_type==F_UNLCK ){ + zType = "UNLCK"; + }else{ + assert( 0 ); + } + assert( p->l_whence==SEEK_SET ); + s = fcntl(fd, op, p); + savedErrno = errno; + sqlite3DebugPrintf("fcntl %d %d %s %s %d %d %d %d\n", + threadid, fd, zOpName, zType, (int)p->l_start, (int)p->l_len, + (int)p->l_pid, s); + if( s && op==F_SETLK && (p->l_type==F_RDLCK || p->l_type==F_WRLCK) ){ + struct flock l2; + l2 = *p; + fcntl(fd, F_GETLK, &l2); + if( l2.l_type==F_RDLCK ){ + zType = "RDLCK"; + }else if( l2.l_type==F_WRLCK ){ + zType = "WRLCK"; + }else if( l2.l_type==F_UNLCK ){ + zType = "UNLCK"; + }else{ + assert( 0 ); + } + sqlite3DebugPrintf("fcntl-failure-reason: %s %d %d %d\n", + zType, (int)l2.l_start, (int)l2.l_len, (int)l2.l_pid); + } + errno = savedErrno; + return s; +} +#define fcntl lockTrace +#endif /* SQLITE_LOCK_TRACE */ + +/* +** The testThreadLockingBehavior() routine launches two separate +** threads on this routine. This routine attempts to lock a file +** descriptor then returns. The success or failure of that attempt +** allows the testThreadLockingBehavior() procedure to determine +** whether or not threads can override each others locks. +*/ +static void *threadLockingTest(void *pArg){ + struct threadTestData *pData = (struct threadTestData*)pArg; + pData->result = fcntl(pData->fd, F_SETLK, &pData->lock); + return pArg; +} + +/* +** This procedure attempts to determine whether or not threads +** can override each others locks then sets the +** threadsOverrideEachOthersLocks variable appropriately. +*/ +static void testThreadLockingBehavior(int fd_orig){ + threadsOverrideEachOthersLocks = 1; +} +#endif /* SQLITE_BEOS_THREADS */ + +/* +** Release a lockInfo structure previously allocated by findLockInfo(). +*/ +static void releaseLockInfo(struct lockInfo *pLock){ + assert( sqlite3OsInMutex(1) ); + pLock->nRef--; + if( pLock->nRef==0 ){ + sqlite3HashInsert(&lockHash, &pLock->key, sizeof(pLock->key), 0); + sqlite3ThreadSafeFree(pLock); + } +} + +/* +** Release a openCnt structure previously allocated by findLockInfo(). +*/ +static void releaseOpenCnt(struct openCnt *pOpen){ + assert( sqlite3OsInMutex(1) ); + pOpen->nRef--; + if( pOpen->nRef==0 ){ + sqlite3HashInsert(&openHash, &pOpen->key, sizeof(pOpen->key), 0); + free(pOpen->aPending); + sqlite3ThreadSafeFree(pOpen); + } +} + +/* +** Given a file descriptor, locate lockInfo and openCnt structures that +** describes that file descriptor. Create new ones if necessary. The +** return values might be uninitialized if an error occurs. +** +** Return the number of errors. +*/ +static int findLockInfo( + int fd, /* The file descriptor used in the key */ + struct lockInfo **ppLock, /* Return the lockInfo structure here */ + struct openCnt **ppOpen /* Return the openCnt structure here */ +){ + int rc; + struct lockKey key1; + struct openKey key2; + struct stat statbuf; + struct lockInfo *pLock; + struct openCnt *pOpen; + rc = fstat(fd, &statbuf); + if( rc!=0 ) return 1; + + assert( sqlite3OsInMutex(1) ); + memset(&key1, 0, sizeof(key1)); + key1.dev = statbuf.st_dev; + key1.ino = statbuf.st_ino; + key1.tid = find_thread(NULL); + + memset(&key2, 0, sizeof(key2)); + key2.dev = statbuf.st_dev; + key2.ino = statbuf.st_ino; + pLock = (struct lockInfo*)sqlite3HashFind(&lockHash, &key1, sizeof(key1)); + if( pLock==0 ){ + struct lockInfo *pOld; + pLock = sqlite3ThreadSafeMalloc( sizeof(*pLock) ); + if( pLock==0 ){ + rc = 1; + goto exit_findlockinfo; + } + pLock->key = key1; + pLock->nRef = 1; + pLock->cnt = 0; + pLock->locktype = 0; + pOld = sqlite3HashInsert(&lockHash, &pLock->key, sizeof(key1), pLock); + if( pOld!=0 ){ + assert( pOld==pLock ); + sqlite3ThreadSafeFree(pLock); + rc = 1; + goto exit_findlockinfo; + } + }else{ + pLock->nRef++; + } + *ppLock = pLock; + if( ppOpen!=0 ){ + pOpen = (struct openCnt*)sqlite3HashFind(&openHash, &key2, sizeof(key2)); + if( pOpen==0 ){ + struct openCnt *pOld; + pOpen = sqlite3ThreadSafeMalloc( sizeof(*pOpen) ); + if( pOpen==0 ){ + releaseLockInfo(pLock); + rc = 1; + goto exit_findlockinfo; + } + pOpen->key = key2; + pOpen->nRef = 1; + pOpen->nLock = 0; + pOpen->nPending = 0; + pOpen->aPending = 0; + pOld = sqlite3HashInsert(&openHash, &pOpen->key, sizeof(key2), pOpen); + if( pOld!=0 ){ + assert( pOld==pOpen ); + sqlite3ThreadSafeFree(pOpen); + releaseLockInfo(pLock); + rc = 1; + goto exit_findlockinfo; + } + }else{ + pOpen->nRef++; + } + *ppOpen = pOpen; + } + +exit_findlockinfo: + return rc; +} + +#ifdef SQLITE_DEBUG +/* +** Helper function for printing out trace information from debugging +** binaries. This returns the string represetation of the supplied +** integer lock-type. +*/ +static const char *locktypeName(int locktype){ + switch( locktype ){ + case NO_LOCK: return "NONE"; + case SHARED_LOCK: return "SHARED"; + case RESERVED_LOCK: return "RESERVED"; + case PENDING_LOCK: return "PENDING"; + case EXCLUSIVE_LOCK: return "EXCLUSIVE"; + } + return "ERROR"; +} +#endif + +/* +** If we are currently in a different thread than the thread that the +** unixFile argument belongs to, then transfer ownership of the unixFile +** over to the current thread. +** +** A unixFile is only owned by a thread on systems where one thread is +** unable to override locks created by a different thread. RedHat9 is +** an example of such a system. +** +** Ownership transfer is only allowed if the unixFile is currently unlocked. +** If the unixFile is locked and an ownership is wrong, then return +** SQLITE_MISUSE. SQLITE_OK is returned if everything works. +*/ +#ifdef SQLITE_BEOS_THREADS +static int transferOwnership(unixFile *pFile){ + int rc; + thread_id hSelf; + if( threadsOverrideEachOthersLocks ){ + /* Ownership transfers not needed on this system */ + return SQLITE_OK; + } + hSelf = find_thread(NULL); + if( pFile->tid == hSelf){ + /* We are still in the same thread */ + TRACE1("No-transfer, same thread\n"); + return SQLITE_OK; + } + if( pFile->locktype!=NO_LOCK ){ + /* We cannot change ownership while we are holding a lock! */ + return SQLITE_MISUSE; + } + TRACE4("Transfer ownership of %d from %d to %d\n", pFile->h,pFile->tid,hSelf); + pFile->tid = hSelf; + releaseLockInfo(pFile->pLock); + rc = findLockInfo(pFile->h, &pFile->pLock, 0); + TRACE5("LOCK %d is now %s(%s,%d)\n", pFile->h, + locktypeName(pFile->locktype), + locktypeName(pFile->pLock->locktype), pFile->pLock->cnt); + return rc; +} +#else + /* On single-threaded builds, ownership transfer is a no-op */ +# define transferOwnership(X) SQLITE_OK +#endif + +/* +** Delete the named file +*/ +int sqlite3BeDelete(const char *zFilename){ + unlink(zFilename); + return SQLITE_OK; +} + +/* +** Return TRUE if the named file exists. +*/ +int sqlite3BeFileExists(const char *zFilename){ + return access(zFilename, 0)==0; +} + +/* Forward declaration */ +static int allocateUnixFile(unixFile *pInit, OsFile **pId); + +/* +** Attempt to open a file for both reading and writing. If that +** fails, try opening it read-only. If the file does not exist, +** try to create it. +** +** On success, a handle for the open file is written to *id +** and *pReadonly is set to 0 if the file was opened for reading and +** writing or 1 if the file was opened read-only. The function returns +** SQLITE_OK. +** +** On failure, the function returns SQLITE_CANTOPEN and leaves +** *id and *pReadonly unchanged. +*/ +int sqlite3BeOpenReadWrite( + const char *zFilename, + OsFile **pId, + int *pReadonly +){ + int rc; + unixFile f; + + CRASH_TEST_OVERRIDE(sqlite3CrashOpenReadWrite, zFilename, pId, pReadonly); + assert( 0==*pId ); + f.h = open(zFilename, O_RDWR|O_CREAT|O_LARGEFILE|O_BINARY, + SQLITE_DEFAULT_FILE_PERMISSIONS); + if( f.h<0 ){ +#ifdef EISDIR + if( errno==EISDIR ){ + return SQLITE_CANTOPEN; + } +#endif + f.h = open(zFilename, O_RDONLY|O_LARGEFILE|O_BINARY); + if( f.h<0 ){ + return SQLITE_CANTOPEN; + } + *pReadonly = 1; + }else{ + *pReadonly = 0; + } + sqlite3OsEnterMutex(); + rc = findLockInfo(f.h, &f.pLock, &f.pOpen); + sqlite3OsLeaveMutex(); + if( rc ){ + close(f.h); + return SQLITE_NOMEM; + } + TRACE3("OPEN %-3d %s\n", f.h, zFilename); + return allocateUnixFile(&f, pId); +} + + +/* +** Attempt to open a new file for exclusive access by this process. +** The file will be opened for both reading and writing. To avoid +** a potential security problem, we do not allow the file to have +** previously existed. Nor do we allow the file to be a symbolic +** link. +** +** If delFlag is true, then make arrangements to automatically delete +** the file when it is closed. +** +** On success, write the file handle into *id and return SQLITE_OK. +** +** On failure, return SQLITE_CANTOPEN. +*/ +int sqlite3BeOpenExclusive(const char *zFilename, OsFile **pId, int delFlag){ + int rc; + unixFile f; + + CRASH_TEST_OVERRIDE(sqlite3CrashOpenExclusive, zFilename, pId, delFlag); + assert( 0==*pId ); + if( access(zFilename, 0)==0 ){ + return SQLITE_CANTOPEN; + } + f.h = open(zFilename, + O_RDWR|O_CREAT|O_EXCL|O_NOFOLLOW|O_LARGEFILE|O_BINARY, + SQLITE_DEFAULT_FILE_PERMISSIONS); + if( f.h<0 ){ + return SQLITE_CANTOPEN; + } + sqlite3OsEnterMutex(); + rc = findLockInfo(f.h, &f.pLock, &f.pOpen); + sqlite3OsLeaveMutex(); + if( rc ){ + close(f.h); + unlink(zFilename); + return SQLITE_NOMEM; + } + if( delFlag ){ + unlink(zFilename); + } + TRACE3("OPEN-EX %-3d %s\n", f.h, zFilename); + return allocateUnixFile(&f, pId); +} + +/* +** Attempt to open a new file for read-only access. +** +** On success, write the file handle into *id and return SQLITE_OK. +** +** On failure, return SQLITE_CANTOPEN. +*/ +int sqlite3BeOpenReadOnly(const char *zFilename, OsFile **pId){ + int rc; + unixFile f; + + CRASH_TEST_OVERRIDE(sqlite3CrashOpenReadOnly, zFilename, pId, 0); + assert( 0==*pId ); + f.h = open(zFilename, O_RDONLY|O_LARGEFILE|O_BINARY); + if( f.h<0 ){ + return SQLITE_CANTOPEN; + } + sqlite3OsEnterMutex(); + rc = findLockInfo(f.h, &f.pLock, &f.pOpen); + sqlite3OsLeaveMutex(); + if( rc ){ + close(f.h); + return SQLITE_NOMEM; + } + TRACE3("OPEN-RO %-3d %s\n", f.h, zFilename); + return allocateUnixFile(&f, pId); +} + +/* +** Attempt to open a file descriptor for the directory that contains a +** file. This file descriptor can be used to fsync() the directory +** in order to make sure the creation of a new file is actually written +** to disk. +** +** This routine is only meaningful for Unix. It is a no-op under +** windows since windows does not support hard links. +** +** On success, a handle for a previously open file at *id is +** updated with the new directory file descriptor and SQLITE_OK is +** returned. +** +** On failure, the function returns SQLITE_CANTOPEN and leaves +** *id unchanged. +*/ +static int unixOpenDirectory( + OsFile *id, + const char *zDirname +){ + unixFile *pFile = (unixFile*)id; + if( pFile==0 ){ + /* Do not open the directory if the corresponding file is not already + ** open. */ + return SQLITE_CANTOPEN; + } + SET_THREADID(pFile); + assert( pFile->dirfd<0 ); + pFile->dirfd = open(zDirname, O_RDONLY|O_BINARY, 0); + if( pFile->dirfd<0 ){ + return SQLITE_CANTOPEN; + } + TRACE3("OPENDIR %-3d %s\n", pFile->dirfd, zDirname); + return SQLITE_OK; +} + +/* +** If the following global variable points to a string which is the +** name of a directory, then that directory will be used to store +** temporary files. +** +** See also the "PRAGMA temp_store_directory" SQL command. +*/ +char *sqlite3_temp_directory = 0; + +/* +** Create a temporary file name in zBuf. zBuf must be big enough to +** hold at least SQLITE_TEMPNAME_SIZE characters. +*/ +int sqlite3BeTempFileName(char *zBuf){ + static const char *azDirs[] = { + 0, + "/var/tmp", + "/tmp", + ".", + }; + static const unsigned char zChars[] = + "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "0123456789"; + int i, j; + struct stat buf; + const char *zDir = "."; + azDirs[0] = sqlite3_temp_directory; + for(i=0; ioffset then read cnt bytes into pBuf. +** Return the number of bytes actually read. Update the offset. +*/ +static int seekAndRead(unixFile *id, void *pBuf, int cnt){ + int got; +#ifdef USE_PREAD + got = pread(id->h, pBuf, cnt, id->offset); +#else + lseek(id->h, id->offset, SEEK_SET); + got = read(id->h, pBuf, cnt); +#endif + if( got>0 ){ + id->offset += got; + } + return got; +} + +/* +** Read data from a file into a buffer. Return SQLITE_OK if all +** bytes were read successfully and SQLITE_IOERR if anything goes +** wrong. +*/ +static int unixRead(OsFile *id, void *pBuf, int amt){ + int got; + assert( id ); + SimulateIOError(SQLITE_IOERR); + TIMER_START; + got = seekAndRead((unixFile*)id, pBuf, amt); + TIMER_END; + TRACE5("READ %-3d %5d %7d %d\n", ((unixFile*)id)->h, got, + last_page, TIMER_ELAPSED); + SEEK(0); + /* if( got<0 ) got = 0; */ + if( got==amt ){ + return SQLITE_OK; + }else{ + return SQLITE_IOERR; + } +} + +/* +** Seek to the offset in id->offset then read cnt bytes into pBuf. +** Return the number of bytes actually read. Update the offset. +*/ +static int seekAndWrite(unixFile *id, const void *pBuf, int cnt){ + int got; +#ifdef USE_PREAD + got = pwrite(id->h, pBuf, cnt, id->offset); +#else + lseek(id->h, id->offset, SEEK_SET); + got = write(id->h, pBuf, cnt); +#endif + if( got>0 ){ + id->offset += got; + } + return got; +} + + +/* +** Write data from a buffer into a file. Return SQLITE_OK on success +** or some other error code on failure. +*/ +static int unixWrite(OsFile *id, const void *pBuf, int amt){ + int wrote = 0; + assert( id ); + assert( amt>0 ); + SimulateIOError(SQLITE_IOERR); + SimulateDiskfullError; + TIMER_START; + while( amt>0 && (wrote = seekAndWrite((unixFile*)id, pBuf, amt))>0 ){ + amt -= wrote; + pBuf = &((char*)pBuf)[wrote]; + } + TIMER_END; + TRACE5("WRITE %-3d %5d %7d %d\n", ((unixFile*)id)->h, wrote, + last_page, TIMER_ELAPSED); + SEEK(0); + if( amt>0 ){ + return SQLITE_FULL; + } + return SQLITE_OK; +} + +/* +** Move the read/write pointer in a file. +*/ +static int unixSeek(OsFile *id, i64 offset){ + assert( id ); + SEEK(offset/1024 + 1); +#ifdef SQLITE_TEST + if( offset ) SimulateDiskfullError +#endif + ((unixFile*)id)->offset = offset; + return SQLITE_OK; +} + +#ifdef SQLITE_TEST +/* +** Count the number of fullsyncs and normal syncs. This is used to test +** that syncs and fullsyncs are occuring at the right times. +*/ +int sqlite3_sync_count = 0; +int sqlite3_fullsync_count = 0; +#endif + +/* +** Use the fdatasync() API only if the HAVE_FDATASYNC macro is defined. +** Otherwise use fsync() in its place. +*/ +#ifndef HAVE_FDATASYNC +# define fdatasync fsync +#endif + +/* +** Define HAVE_FULLFSYNC to 0 or 1 depending on whether or not +** the F_FULLFSYNC macro is defined. F_FULLFSYNC is currently +** only available on Mac OS X. But that could change. +*/ +#ifdef F_FULLFSYNC +# define HAVE_FULLFSYNC 1 +#else +# define HAVE_FULLFSYNC 0 +#endif + + +/* +** The fsync() system call does not work as advertised on many +** unix systems. The following procedure is an attempt to make +** it work better. +** +** The SQLITE_NO_SYNC macro disables all fsync()s. This is useful +** for testing when we want to run through the test suite quickly. +** You are strongly advised *not* to deploy with SQLITE_NO_SYNC +** enabled, however, since with SQLITE_NO_SYNC enabled, an OS crash +** or power failure will likely corrupt the database file. +*/ +static int full_fsync(int fd, int fullSync, int dataOnly){ + int rc; + + /* Record the number of times that we do a normal fsync() and + ** FULLSYNC. This is used during testing to verify that this procedure + ** gets called with the correct arguments. + */ +#ifdef SQLITE_TEST + if( fullSync ) sqlite3_fullsync_count++; + sqlite3_sync_count++; +#endif + + /* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a + ** no-op + */ +#ifdef SQLITE_NO_SYNC + rc = SQLITE_OK; +#else + +#if HAVE_FULLFSYNC + if( fullSync ){ + rc = fcntl(fd, F_FULLFSYNC, 0); + }else{ + rc = 1; + } + /* If the FULLSYNC failed, try to do a normal fsync() */ + if( rc ) rc = fsync(fd); + +#else /* if !defined(F_FULLSYNC) */ + if( dataOnly ){ + rc = fdatasync(fd); + }else{ + rc = fsync(fd); + } +#endif /* defined(F_FULLFSYNC) */ +#endif /* defined(SQLITE_NO_SYNC) */ + + return rc; +} + +/* +** Make sure all writes to a particular file are committed to disk. +** +** If dataOnly==0 then both the file itself and its metadata (file +** size, access time, etc) are synced. If dataOnly!=0 then only the +** file data is synced. +** +** Under Unix, also make sure that the directory entry for the file +** has been created by fsync-ing the directory that contains the file. +** If we do not do this and we encounter a power failure, the directory +** entry for the journal might not exist after we reboot. The next +** SQLite to access the file will not know that the journal exists (because +** the directory entry for the journal was never created) and the transaction +** will not roll back - possibly leading to database corruption. +*/ +static int unixSync(OsFile *id, int dataOnly){ + unixFile *pFile = (unixFile*)id; + assert( pFile ); + SimulateIOError(SQLITE_IOERR); + TRACE2("SYNC %-3d\n", pFile->h); + if( full_fsync(pFile->h, pFile->fullSync, dataOnly) ){ + return SQLITE_IOERR; + } + if( pFile->dirfd>=0 ){ + TRACE4("DIRSYNC %-3d (have_fullfsync=%d fullsync=%d)\n", pFile->dirfd, + HAVE_FULLFSYNC, pFile->fullSync); +#ifndef SQLITE_DISABLE_DIRSYNC + /* The directory sync is only attempted if full_fsync is + ** turned off or unavailable. If a full_fsync occurred above, + ** then the directory sync is superfluous. + */ + if( (!HAVE_FULLFSYNC || !pFile->fullSync) && full_fsync(pFile->dirfd,0,0) ){ + /* + ** We have received multiple reports of fsync() returning + ** errors when applied to directories on certain file systems. + ** A failed directory sync is not a big deal. So it seems + ** better to ignore the error. Ticket #1657 + */ + /* return SQLITE_IOERR; */ + } +#endif + close(pFile->dirfd); /* Only need to sync once, so close the directory */ + pFile->dirfd = -1; /* when we are done. */ + } + return SQLITE_OK; +} + +/* +** Sync the directory zDirname. This is a no-op on operating systems other +** than UNIX. +** +** This is used to make sure the master journal file has truely been deleted +** before making changes to individual journals on a multi-database commit. +** The F_FULLFSYNC option is not needed here. +*/ +int sqlite3BeSyncDirectory(const char *zDirname){ +#ifdef SQLITE_DISABLE_DIRSYNC + return SQLITE_OK; +#else + int fd; + int r; + SimulateIOError(SQLITE_IOERR); + fd = open(zDirname, O_RDONLY|O_BINARY, 0); + TRACE3("DIRSYNC %-3d (%s)\n", fd, zDirname); + if( fd<0 ){ + return SQLITE_CANTOPEN; + } + r = fsync(fd); + close(fd); + return ((r==0)?SQLITE_OK:SQLITE_IOERR); +#endif +} + +/* +** Truncate an open file to a specified size +*/ +static int unixTruncate(OsFile *id, i64 nByte){ + assert( id ); + SimulateIOError(SQLITE_IOERR); + return ftruncate(((unixFile*)id)->h, nByte)==0 ? SQLITE_OK : SQLITE_IOERR; +} + +/* +** Determine the current size of a file in bytes +*/ +static int unixFileSize(OsFile *id, i64 *pSize){ + struct stat buf; + assert( id ); + SimulateIOError(SQLITE_IOERR); + if( fstat(((unixFile*)id)->h, &buf)!=0 ){ + return SQLITE_IOERR; + } + *pSize = buf.st_size; + return SQLITE_OK; +} + +/* +** This routine checks if there is a RESERVED lock held on the specified +** file by this or any other process. If such a lock is held, return +** non-zero. If the file is unlocked or holds only SHARED locks, then +** return zero. +*/ +static int unixCheckReservedLock(OsFile *id){ + int r = 0; + unixFile *pFile = (unixFile*)id; + + assert( pFile ); + sqlite3OsEnterMutex(); /* Because pFile->pLock is shared across threads */ + + /* Check if a thread in this process holds such a lock */ + if( pFile->pLock->locktype>SHARED_LOCK ){ + r = 1; + } + + /* Otherwise see if some other process holds it. + */ + if( !r ){ + struct flock lock; + lock.l_whence = SEEK_SET; + lock.l_start = RESERVED_BYTE; + lock.l_len = 1; + lock.l_type = F_WRLCK; + fcntl(pFile->h, F_GETLK, &lock); + if( lock.l_type!=F_UNLCK ){ + r = 1; + } + } + + sqlite3OsLeaveMutex(); + TRACE3("TEST WR-LOCK %d %d\n", pFile->h, r); + + return r; +} + +/* +** Lock the file with the lock specified by parameter locktype - one +** of the following: +** +** (1) SHARED_LOCK +** (2) RESERVED_LOCK +** (3) PENDING_LOCK +** (4) EXCLUSIVE_LOCK +** +** Sometimes when requesting one lock state, additional lock states +** are inserted in between. The locking might fail on one of the later +** transitions leaving the lock state different from what it started but +** still short of its goal. The following chart shows the allowed +** transitions and the inserted intermediate states: +** +** UNLOCKED -> SHARED +** SHARED -> RESERVED +** SHARED -> (PENDING) -> EXCLUSIVE +** RESERVED -> (PENDING) -> EXCLUSIVE +** PENDING -> EXCLUSIVE +** +** This routine will only increase a lock. Use the sqlite3OsUnlock() +** routine to lower a locking level. +*/ +static int unixLock(OsFile *id, int locktype){ + /* The following describes the implementation of the various locks and + ** lock transitions in terms of the POSIX advisory shared and exclusive + ** lock primitives (called read-locks and write-locks below, to avoid + ** confusion with SQLite lock names). The algorithms are complicated + ** slightly in order to be compatible with windows systems simultaneously + ** accessing the same database file, in case that is ever required. + ** + ** Symbols defined in os.h indentify the 'pending byte' and the 'reserved + ** byte', each single bytes at well known offsets, and the 'shared byte + ** range', a range of 510 bytes at a well known offset. + ** + ** To obtain a SHARED lock, a read-lock is obtained on the 'pending + ** byte'. If this is successful, a random byte from the 'shared byte + ** range' is read-locked and the lock on the 'pending byte' released. + ** + ** A process may only obtain a RESERVED lock after it has a SHARED lock. + ** A RESERVED lock is implemented by grabbing a write-lock on the + ** 'reserved byte'. + ** + ** A process may only obtain a PENDING lock after it has obtained a + ** SHARED lock. A PENDING lock is implemented by obtaining a write-lock + ** on the 'pending byte'. This ensures that no new SHARED locks can be + ** obtained, but existing SHARED locks are allowed to persist. A process + ** does not have to obtain a RESERVED lock on the way to a PENDING lock. + ** This property is used by the algorithm for rolling back a journal file + ** after a crash. + ** + ** An EXCLUSIVE lock, obtained after a PENDING lock is held, is + ** implemented by obtaining a write-lock on the entire 'shared byte + ** range'. Since all other locks require a read-lock on one of the bytes + ** within this range, this ensures that no other locks are held on the + ** database. + ** + ** The reason a single byte cannot be used instead of the 'shared byte + ** range' is that some versions of windows do not support read-locks. By + ** locking a random byte from a range, concurrent SHARED locks may exist + ** even if the locking primitive used is always a write-lock. + */ + int rc = SQLITE_OK; + unixFile *pFile = (unixFile*)id; + struct lockInfo *pLock = pFile->pLock; + struct flock lock; + int s; + + assert( pFile ); + TRACE7("LOCK %d %s was %s(%s,%d) pid=%d\n", pFile->h, + locktypeName(locktype), locktypeName(pFile->locktype), + locktypeName(pLock->locktype), pLock->cnt , getpid()); + + /* If there is already a lock of this type or more restrictive on the + ** OsFile, do nothing. Don't use the end_lock: exit path, as + ** sqlite3OsEnterMutex() hasn't been called yet. + */ + if( pFile->locktype>=locktype ){ + TRACE3("LOCK %d %s ok (already held)\n", pFile->h, + locktypeName(locktype)); + return SQLITE_OK; + } + + /* Make sure the locking sequence is correct + */ + assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK ); + assert( locktype!=PENDING_LOCK ); + assert( locktype!=RESERVED_LOCK || pFile->locktype==SHARED_LOCK ); + + /* This mutex is needed because pFile->pLock is shared across threads + */ + sqlite3OsEnterMutex(); + + /* Make sure the current thread owns the pFile. + */ + rc = transferOwnership(pFile); + if( rc!=SQLITE_OK ){ + sqlite3OsLeaveMutex(); + return rc; + } + pLock = pFile->pLock; + + /* If some thread using this PID has a lock via a different OsFile* + ** handle that precludes the requested lock, return BUSY. + */ + if( (pFile->locktype!=pLock->locktype && + (pLock->locktype>=PENDING_LOCK || locktype>SHARED_LOCK)) + ){ + rc = SQLITE_BUSY; + goto end_lock; + } + + /* If a SHARED lock is requested, and some thread using this PID already + ** has a SHARED or RESERVED lock, then increment reference counts and + ** return SQLITE_OK. + */ + if( locktype==SHARED_LOCK && + (pLock->locktype==SHARED_LOCK || pLock->locktype==RESERVED_LOCK) ){ + assert( locktype==SHARED_LOCK ); + assert( pFile->locktype==0 ); + assert( pLock->cnt>0 ); + pFile->locktype = SHARED_LOCK; + pLock->cnt++; + pFile->pOpen->nLock++; + goto end_lock; + } + + lock.l_len = 1L; + + lock.l_whence = SEEK_SET; + + /* A PENDING lock is needed before acquiring a SHARED lock and before + ** acquiring an EXCLUSIVE lock. For the SHARED lock, the PENDING will + ** be released. + */ + if( locktype==SHARED_LOCK + || (locktype==EXCLUSIVE_LOCK && pFile->locktypeh, F_SETLK, &lock); + if( s ){ + rc = (errno==EINVAL) ? SQLITE_NOLFS : SQLITE_BUSY; + goto end_lock; + } + } + + + /* If control gets to this point, then actually go ahead and make + ** operating system calls for the specified lock. + */ + if( locktype==SHARED_LOCK ){ + assert( pLock->cnt==0 ); + assert( pLock->locktype==0 ); + + /* Now get the read-lock */ + lock.l_start = SHARED_FIRST; + lock.l_len = SHARED_SIZE; + s = fcntl(pFile->h, F_SETLK, &lock); + + /* Drop the temporary PENDING lock */ + lock.l_start = PENDING_BYTE; + lock.l_len = 1L; + lock.l_type = F_UNLCK; + if( fcntl(pFile->h, F_SETLK, &lock)!=0 ){ + rc = SQLITE_IOERR; /* This should never happen */ + goto end_lock; + } + if( s ){ + rc = (errno==EINVAL) ? SQLITE_NOLFS : SQLITE_BUSY; + }else{ + pFile->locktype = SHARED_LOCK; + pFile->pOpen->nLock++; + pLock->cnt = 1; + } + }else if( locktype==EXCLUSIVE_LOCK && pLock->cnt>1 ){ + /* We are trying for an exclusive lock but another thread in this + ** same process is still holding a shared lock. */ + rc = SQLITE_BUSY; + }else{ + /* The request was for a RESERVED or EXCLUSIVE lock. It is + ** assumed that there is a SHARED or greater lock on the file + ** already. + */ + assert( 0!=pFile->locktype ); + lock.l_type = F_WRLCK; + switch( locktype ){ + case RESERVED_LOCK: + lock.l_start = RESERVED_BYTE; + break; + case EXCLUSIVE_LOCK: + lock.l_start = SHARED_FIRST; + lock.l_len = SHARED_SIZE; + break; + default: + assert(0); + } + s = fcntl(pFile->h, F_SETLK, &lock); + if( s ){ + rc = (errno==EINVAL) ? SQLITE_NOLFS : SQLITE_BUSY; + } + } + + if( rc==SQLITE_OK ){ + pFile->locktype = locktype; + pLock->locktype = locktype; + }else if( locktype==EXCLUSIVE_LOCK ){ + pFile->locktype = PENDING_LOCK; + pLock->locktype = PENDING_LOCK; + } + +end_lock: + sqlite3OsLeaveMutex(); + TRACE4("LOCK %d %s %s\n", pFile->h, locktypeName(locktype), + rc==SQLITE_OK ? "ok" : "failed"); + return rc; +} + +/* +** Lower the locking level on file descriptor pFile to locktype. locktype +** must be either NO_LOCK or SHARED_LOCK. +** +** If the locking level of the file descriptor is already at or below +** the requested locking level, this routine is a no-op. +*/ +static int unixUnlock(OsFile *id, int locktype){ + struct lockInfo *pLock; + struct flock lock; + int rc = SQLITE_OK; + unixFile *pFile = (unixFile*)id; + + assert( pFile ); + TRACE7("UNLOCK %d %d was %d(%d,%d) pid=%d\n", pFile->h, locktype, + pFile->locktype, pFile->pLock->locktype, pFile->pLock->cnt, getpid()); + + assert( locktype<=SHARED_LOCK ); + if( pFile->locktype<=locktype ){ + return SQLITE_OK; + } + if( CHECK_THREADID(pFile) ){ + return SQLITE_MISUSE; + } + sqlite3OsEnterMutex(); + pLock = pFile->pLock; + assert( pLock->cnt!=0 ); + if( pFile->locktype>SHARED_LOCK ){ + assert( pLock->locktype==pFile->locktype ); + if( locktype==SHARED_LOCK ){ + lock.l_type = F_RDLCK; + lock.l_whence = SEEK_SET; + lock.l_start = SHARED_FIRST; + lock.l_len = SHARED_SIZE; + if( fcntl(pFile->h, F_SETLK, &lock)!=0 ){ + /* This should never happen */ + rc = SQLITE_IOERR; + } + } + lock.l_type = F_UNLCK; + lock.l_whence = SEEK_SET; + lock.l_start = PENDING_BYTE; + lock.l_len = 2L; assert( PENDING_BYTE+1==RESERVED_BYTE ); + if( fcntl(pFile->h, F_SETLK, &lock)==0 ){ + pLock->locktype = SHARED_LOCK; + }else{ + rc = SQLITE_IOERR; /* This should never happen */ + } + } + if( locktype==NO_LOCK ){ + struct openCnt *pOpen; + + /* Decrement the shared lock counter. Release the lock using an + ** OS call only when all threads in this same process have released + ** the lock. + */ + pLock->cnt--; + if( pLock->cnt==0 ){ + lock.l_type = F_UNLCK; + lock.l_whence = SEEK_SET; + lock.l_start = lock.l_len = 0L; + if( fcntl(pFile->h, F_SETLK, &lock)==0 ){ + pLock->locktype = NO_LOCK; + }else{ + rc = SQLITE_IOERR; /* This should never happen */ + } + } + + /* Decrement the count of locks against this same file. When the + ** count reaches zero, close any other file descriptors whose close + ** was deferred because of outstanding locks. + */ + pOpen = pFile->pOpen; + pOpen->nLock--; + assert( pOpen->nLock>=0 ); + if( pOpen->nLock==0 && pOpen->nPending>0 ){ + int i; + for(i=0; inPending; i++){ + close(pOpen->aPending[i]); + } + free(pOpen->aPending); + pOpen->nPending = 0; + pOpen->aPending = 0; + } + } + sqlite3OsLeaveMutex(); + pFile->locktype = locktype; + return rc; +} + +/* +** Close a file. +*/ +static int unixClose(OsFile **pId){ + unixFile *id = (unixFile*)*pId; + + if( !id ) return SQLITE_OK; + unixUnlock(*pId, NO_LOCK); + if( id->dirfd>=0 ) close(id->dirfd); + id->dirfd = -1; + sqlite3OsEnterMutex(); + + if( id->pOpen->nLock ){ + /* If there are outstanding locks, do not actually close the file just + ** yet because that would clear those locks. Instead, add the file + ** descriptor to pOpen->aPending. It will be automatically closed when + ** the last lock is cleared. + */ + int *aNew; + struct openCnt *pOpen = id->pOpen; + aNew = realloc( pOpen->aPending, (pOpen->nPending+1)*sizeof(int) ); + if( aNew==0 ){ + /* If a malloc fails, just leak the file descriptor */ + }else{ + pOpen->aPending = aNew; + pOpen->aPending[pOpen->nPending] = id->h; + pOpen->nPending++; + } + }else{ + /* There are no outstanding locks so we can close the file immediately */ + close(id->h); + } + releaseLockInfo(id->pLock); + releaseOpenCnt(id->pOpen); + + sqlite3OsLeaveMutex(); + id->isOpen = 0; + TRACE2("CLOSE %-3d\n", id->h); + OpenCounter(-1); + sqlite3ThreadSafeFree(id); + *pId = 0; + return SQLITE_OK; +} + +/* +** Turn a relative pathname into a full pathname. Return a pointer +** to the full pathname stored in space obtained from sqliteMalloc(). +** The calling function is responsible for freeing this space once it +** is no longer needed. +*/ +char *sqlite3BeFullPathname(const char *zRelative){ + char *zFull = 0; + if( zRelative[0]=='/' ){ + sqlite3SetString(&zFull, zRelative, (char*)0); + }else{ + char *zBuf = sqliteMalloc(5000); + if( zBuf==0 ){ + return 0; + } + zBuf[0] = 0; + sqlite3SetString(&zFull, getcwd(zBuf, 5000), "/", zRelative, + (char*)0); + sqliteFree(zBuf); + } + +#if 0 + /* + ** Remove "/./" path elements and convert "/A/./" path elements + ** to just "/". + */ + if( zFull ){ + int i, j; + for(i=j=0; zFull[i]; i++){ + if( zFull[i]=='/' ){ + if( zFull[i+1]=='/' ) continue; + if( zFull[i+1]=='.' && zFull[i+2]=='/' ){ + i += 1; + continue; + } + if( zFull[i+1]=='.' && zFull[i+2]=='.' && zFull[i+3]=='/' ){ + while( j>0 && zFull[j-1]!='/' ){ j--; } + i += 3; + continue; + } + } + zFull[j++] = zFull[i]; + } + zFull[j] = 0; + } +#endif + + return zFull; +} + +/* +** Change the value of the fullsync flag in the given file descriptor. +*/ +static void unixSetFullSync(OsFile *id, int v){ + ((unixFile*)id)->fullSync = v; +} + +/* +** Return the underlying file handle for an OsFile +*/ +static int unixFileHandle(OsFile *id){ + return ((unixFile*)id)->h; +} + +/* +** Return an integer that indices the type of lock currently held +** by this handle. (Used for testing and analysis only.) +*/ +static int unixLockState(OsFile *id){ + return ((unixFile*)id)->locktype; +} + +/* +** This vector defines all the methods that can operate on an OsFile +** for unix. +*/ +static const IoMethod sqlite3BeIoMethod = { + unixClose, + unixOpenDirectory, + unixRead, + unixWrite, + unixSeek, + unixTruncate, + unixSync, + unixSetFullSync, + unixFileHandle, + unixFileSize, + unixLock, + unixUnlock, + unixLockState, + unixCheckReservedLock, +}; + +/* +** Allocate memory for a unixFile. Initialize the new unixFile +** to the value given in pInit and return a pointer to the new +** OsFile. If we run out of memory, close the file and return NULL. +*/ +static int allocateUnixFile(unixFile *pInit, OsFile **pId){ + unixFile *pNew; + pInit->dirfd = -1; + pInit->fullSync = 0; + pInit->locktype = 0; + pInit->offset = 0; + SET_THREADID(pInit); + pNew = sqlite3ThreadSafeMalloc( sizeof(unixFile) ); + if( pNew==0 ){ + close(pInit->h); + sqlite3OsEnterMutex(); + releaseLockInfo(pInit->pLock); + releaseOpenCnt(pInit->pOpen); + sqlite3OsLeaveMutex(); + *pId = 0; + return SQLITE_NOMEM; + }else{ + *pNew = *pInit; + pNew->pMethod = &sqlite3BeIoMethod; + *pId = (OsFile*)pNew; + OpenCounter(+1); + return SQLITE_OK; + } +} + + +#endif /* SQLITE_OMIT_DISKIO */ +/*************************************************************************** +** Everything above deals with file I/O. Everything that follows deals +** with other miscellanous aspects of the operating system interface +****************************************************************************/ + + +/* +** Get information to seed the random number generator. The seed +** is written into the buffer zBuf[256]. The calling function must +** supply a sufficiently large buffer. +*/ +int sqlite3BeRandomSeed(char *zBuf){ + /* We have to initialize zBuf to prevent valgrind from reporting + ** errors. The reports issued by valgrind are incorrect - we would + ** prefer that the randomness be increased by making use of the + ** uninitialized space in zBuf - but valgrind errors tend to worry + ** some users. Rather than argue, it seems easier just to initialize + ** the whole array and silence valgrind, even if that means less randomness + ** in the random seed. + ** + ** When testing, initializing zBuf[] to zero is all we do. That means + ** that we always use the same random number sequence. This makes the + ** tests repeatable. + */ + memset(zBuf, 0, 256); +#if !defined(SQLITE_TEST) + { + int pid, fd; + fd = open("/dev/urandom", O_RDONLY); + if( fd<0 ){ + time_t t; + time(&t); + memcpy(zBuf, &t, sizeof(t)); + pid = getpid(); + memcpy(&zBuf[sizeof(time_t)], &pid, sizeof(pid)); + }else{ + read(fd, zBuf, 256); + close(fd); + } + } +#endif + return SQLITE_OK; +} + +/* +** Sleep for a little while. Return the amount of time slept. +** The argument is the number of milliseconds we want to sleep. +*/ +int sqlite3BeSleep(int ms){ +#if defined(HAVE_USLEEP) && HAVE_USLEEP + usleep(ms*1000); + return ms; +#else + sleep((ms+999)/1000); + return 1000*((ms+999)/1000); +#endif +} + +/* +** Static variables used for thread synchronization. +** +** inMutex the nesting depth of the recursive mutex. The thread +** holding mutexMain can read this variable at any time. +** But is must hold mutexAux to change this variable. Other +** threads must hold mutexAux to read the variable and can +** never write. +** +** mutexOwner The thread id of the thread holding mutexMain. Same +** access rules as for inMutex. +** +** mutexOwnerValid True if the value in mutexOwner is valid. The same +** access rules apply as for inMutex. +** +** mutexMain The main mutex. Hold this mutex in order to get exclusive +** access to SQLite data structures. +** +** mutexAux An auxiliary mutex needed to access variables defined above. +** +** Mutexes are always acquired in this order: mutexMain mutexAux. It +** is not necessary to acquire mutexMain in order to get mutexAux - just +** do not attempt to acquire them in the reverse order: mutexAux mutexMain. +** Either get the mutexes with mutexMain first or get mutexAux only. +** +** When running on a platform where the three variables inMutex, mutexOwner, +** and mutexOwnerValid can be set atomically, the mutexAux is not required. +** On many systems, all three are 32-bit integers and writing to a 32-bit +** integer is atomic. I think. But there are no guarantees. So it seems +** safer to protect them using mutexAux. +*/ +static int inMutex = 0; +#ifdef SQLITE_BEOS_THREADS +static thread_id mutexOwner; /* Thread holding mutexMain */ +static int mutexOwnerValid = 0; /* True if mutexOwner is valid */ +static sem_id mutexMain = -1; /* The mutex */ +static sem_id mutexAux = -1; /* Aux mutex */ +#endif + +/* +** The following pair of routine implement mutual exclusion for +** multi-threaded processes. Only a single thread is allowed to +** executed code that is surrounded by EnterMutex() and LeaveMutex(). +** +** SQLite uses only a single Mutex. There is not much critical +** code and what little there is executes quickly and without blocking. +** +** As of version 3.3.2, this mutex must be recursive. +*/ +void sqlite3BeEnterMutex(){ +#ifdef SQLITE_BEOS_THREADS + if (mutexAux == -1 || mutexMain == -1) + { + mutexAux = create_sem(1, "mutexAux"); + mutexMain = create_sem(1, "mutexMain"); + } + acquire_sem(mutexAux); + if( !mutexOwnerValid || (mutexOwner != find_thread(NULL))) { + release_sem(mutexAux); + acquire_sem(mutexMain); + assert( inMutex==0 ); + assert( !mutexOwnerValid ); + acquire_sem(mutexAux); + mutexOwner = find_thread(NULL); + mutexOwnerValid = 1; + } + inMutex++; + release_sem(mutexAux); +#else + inMutex++; +#endif +} +void sqlite3BeLeaveMutex(){ + assert( inMutex>0 ); +#ifdef SQLITE_BEOS_THREADS + acquire_sem(mutexAux); + inMutex--; + assert( mutexOwner == find_thread(NULL) ); + if( inMutex==0 ){ + assert( mutexOwnerValid ); + mutexOwnerValid = 0; + release_sem(mutexMain); + } + release_sem(mutexAux); +#else + inMutex--; +#endif +} + +/* +** Return TRUE if the mutex is currently held. +** +** If the thisThrd parameter is true, return true only if the +** calling thread holds the mutex. If the parameter is false, return +** true if any thread holds the mutex. +*/ +int sqlite3BeInMutex(int thisThrd){ +#ifdef SQLITE_BEOS_THREADS + int rc; + acquire_sem(mutexAux); + rc = inMutex>0 && (thisThrd==0 || (mutexOwner == find_thread(NULL))); + release_sem(mutexAux); + return rc; +#else + return inMutex>0; +#endif +} + +/* +** Remember the number of thread-specific-data blocks allocated. +** Use this to verify that we are not leaking thread-specific-data. +** Ticket #1601 +*/ +#ifdef SQLITE_TEST +int sqlite3_tsd_count = 0; +# ifdef SQLITE_BEOS_THREADS + static sem_id tsd_counter_mutex = create_sem(1, "tsd_counter"); +# define TSD_COUNTER(N) \ + acquire_sem(tsd_counter_mutex); \ + sqlite3_tsd_count += N; \ + release_sem(tsd_counter_mutex); +# else +# define TSD_COUNTER(N) sqlite3_tsd_count += N +# endif +#else +# define TSD_COUNTER(N) /* no-op */ +#endif + +/* +** If called with allocateFlag>0, then return a pointer to thread +** specific data for the current thread. Allocate and zero the +** thread-specific data if it does not already exist. +** +** If called with allocateFlag==0, then check the current thread +** specific data. Return it if it exists. If it does not exist, +** then return NULL. +** +** If called with allocateFlag<0, check to see if the thread specific +** data is allocated and is all zero. If it is then deallocate it. +** Return a pointer to the thread specific data or NULL if it is +** unallocated or gets deallocated. +*/ +ThreadData *sqlite3BeThreadSpecificData(int allocateFlag){ + static const ThreadData zeroData = {0}; /* Initializer to silence warnings + ** from broken compilers */ +#ifdef SQLITE_BEOS_THREADS + static int32 key; + static int keyInit = 0; + ThreadData *pTsd; + + if( !keyInit ){ + sqlite3OsEnterMutex(); + if( !keyInit ){ + key = tls_allocate(); + if( key < 0 ){ + sqlite3OsLeaveMutex(); + return 0; + } + keyInit = 1; + } + sqlite3OsLeaveMutex(); + } + + pTsd = tls_get(key); + if( allocateFlag>0 ){ + if( pTsd==0 ){ + if( !sqlite3TestMallocFail() ){ + pTsd = sqlite3OsMalloc(sizeof(zeroData)); + } +#ifdef SQLITE_MEMDEBUG + sqlite3_isFail = 0; +#endif + if( pTsd ){ + *pTsd = zeroData; + tls_set(key, pTsd); + TSD_COUNTER(+1); + } + } + }else if( pTsd!=0 && allocateFlag<0 + && memcmp(pTsd, &zeroData, sizeof(ThreadData))==0 ){ + sqlite3OsFree(pTsd); + tls_set(key, 0); + TSD_COUNTER(-1); + pTsd = 0; + } + return pTsd; +#else + static ThreadData *pTsd = 0; + if( allocateFlag>0 ){ + if( pTsd==0 ){ + if( !sqlite3TestMallocFail() ){ + pTsd = sqlite3OsMalloc( sizeof(zeroData) ); + } +#ifdef SQLITE_MEMDEBUG + sqlite3_isFail = 0; +#endif + if( pTsd ){ + *pTsd = zeroData; + TSD_COUNTER(+1); + } + } + }else if( pTsd!=0 && allocateFlag<0 + && memcmp(pTsd, &zeroData, sizeof(ThreadData))==0 ){ + sqlite3OsFree(pTsd); + TSD_COUNTER(-1); + pTsd = 0; + } + return pTsd; +#endif +} + +/* +** The following variable, if set to a non-zero value, becomes the result +** returned from sqlite3OsCurrentTime(). This is used for testing. +*/ +#ifdef SQLITE_TEST +int sqlite3_current_time = 0; +#endif + +/* +** Find the current time (in Universal Coordinated Time). Write the +** current time and date as a Julian Day number into *prNow and +** return 0. Return 1 if the time and date cannot be found. +*/ +int sqlite3BeCurrentTime(double *prNow){ +#ifdef NO_GETTOD + time_t t; + time(&t); + *prNow = t/86400.0 + 2440587.5; +#else + struct timeval sNow; + struct timezone sTz; /* Not used */ + gettimeofday(&sNow, &sTz); + *prNow = 2440587.5 + sNow.tv_sec/86400.0 + sNow.tv_usec/86400000000.0; +#endif +#ifdef SQLITE_TEST + if( sqlite3_current_time ){ + *prNow = sqlite3_current_time/86400.0 + 2440587.5; + } +#endif + return 0; +} + +#endif /* OS_BEOS */ diff --git a/mozilla/gfx/cairo/cairo/src/cairo-analysis-surface-private.h b/mozilla/gfx/cairo/cairo/src/cairo-analysis-surface-private.h new file mode 100644 index 00000000000..f89b55cc8d9 --- /dev/null +++ b/mozilla/gfx/cairo/cairo/src/cairo-analysis-surface-private.h @@ -0,0 +1,55 @@ +/* $Id: cairo-analysis-surface-private.h,v 1.1 2006-06-05 23:16:24 vladimir%pobox.com Exp $ + * + * Copyright © 2005 Keith Packard + * + * This library is free software; you can redistribute it and/or + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. + * + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * The Original Code is the cairo graphics library. + * + * The Initial Developer of the Original Code is Keith Packard + * + * Contributor(s): + * Keith Packard + */ + +#ifndef CAIRO_ANALYSIS_SURFACE_H +#define CAIRO_ANALYSIS_SURFACE_H + +#include "cairoint.h" + +cairo_private cairo_surface_t * +_cairo_analysis_surface_create (cairo_surface_t *target, + int width, + int height); + +cairo_private pixman_region16_t * +_cairo_analysis_surface_get_supported (cairo_surface_t *surface); + +cairo_private pixman_region16_t * +_cairo_analysis_surface_get_unsupported (cairo_surface_t *unsupported); + +cairo_private cairo_bool_t +_cairo_analysis_surface_has_unsupported (cairo_surface_t *unsupported); + +#endif /* CAIRO_ANALYSIS_SURFACE_H */ diff --git a/mozilla/gfx/cairo/cairo/src/cairo-analysis-surface.c b/mozilla/gfx/cairo/cairo/src/cairo-analysis-surface.c new file mode 100644 index 00000000000..fdcd17fd3f5 --- /dev/null +++ b/mozilla/gfx/cairo/cairo/src/cairo-analysis-surface.c @@ -0,0 +1,259 @@ +/* + * Copyright © 2006 Keith Packard + * + * This library is free software; you can redistribute it and/or + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. + * + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * The Original Code is the cairo graphics library. + * + * The Initial Developer of the Original Code is Keith Packard + * + * Contributor(s): + * Keith Packard + */ + +#include "cairoint.h" + +#include "cairo-analysis-surface-private.h" +#include "cairo-paginated-surface-private.h" + +typedef struct { + cairo_surface_t base; + int width; + int height; + + cairo_surface_t *target; + + cairo_bool_t fallback; +} cairo_analysis_surface_t; + +static cairo_int_status_t +_cairo_analysis_surface_get_extents (void *abstract_surface, + cairo_rectangle_fixed_t *rectangle) +{ + cairo_analysis_surface_t *surface = abstract_surface; + + return _cairo_surface_get_extents (surface->target, rectangle); +} + +static cairo_int_status_t +_cairo_analysis_surface_paint (void *abstract_surface, + cairo_operator_t op, + cairo_pattern_t *source) +{ + cairo_analysis_surface_t *surface = abstract_surface; + cairo_status_t status; + + if (!surface->target->backend->paint) + status = CAIRO_INT_STATUS_UNSUPPORTED; + else + status = (*surface->target->backend->paint) (surface->target, op, + source); + if (status == CAIRO_INT_STATUS_UNSUPPORTED) { + surface->fallback = TRUE; + status = CAIRO_STATUS_SUCCESS; + } + return status; +} + +static cairo_int_status_t +_cairo_analysis_surface_mask (void *abstract_surface, + cairo_operator_t op, + cairo_pattern_t *source, + cairo_pattern_t *mask) +{ + cairo_analysis_surface_t *surface = abstract_surface; + cairo_status_t status; + + if (!surface->target->backend->mask) + status = CAIRO_INT_STATUS_UNSUPPORTED; + else + status = (*surface->target->backend->mask) (surface->target, op, + source, mask); + if (status == CAIRO_INT_STATUS_UNSUPPORTED) { + surface->fallback = TRUE; + status = CAIRO_STATUS_SUCCESS; + } + return status; +} + +static cairo_int_status_t +_cairo_analysis_surface_stroke (void *abstract_surface, + cairo_operator_t op, + cairo_pattern_t *source, + cairo_path_fixed_t *path, + cairo_stroke_style_t *style, + cairo_matrix_t *ctm, + cairo_matrix_t *ctm_inverse, + double tolerance, + cairo_antialias_t antialias) +{ + cairo_analysis_surface_t *surface = abstract_surface; + cairo_status_t status; + + if (!surface->target->backend->stroke) + status = CAIRO_INT_STATUS_UNSUPPORTED; + else + status = (*surface->target->backend->stroke) (surface->target, op, + source, path, style, + ctm, ctm_inverse, + tolerance, antialias); + if (status == CAIRO_INT_STATUS_UNSUPPORTED) { + surface->fallback = TRUE; + status = CAIRO_STATUS_SUCCESS; + } + return status; +} + +static cairo_int_status_t +_cairo_analysis_surface_fill (void *abstract_surface, + cairo_operator_t op, + cairo_pattern_t *source, + cairo_path_fixed_t *path, + cairo_fill_rule_t fill_rule, + double tolerance, + cairo_antialias_t antialias) +{ + cairo_analysis_surface_t *surface = abstract_surface; + cairo_status_t status; + + if (!surface->target->backend->fill) + status = CAIRO_INT_STATUS_UNSUPPORTED; + else + status = (*surface->target->backend->fill) (surface->target, op, + source, path, fill_rule, + tolerance, antialias); + if (status == CAIRO_INT_STATUS_UNSUPPORTED) { + surface->fallback = TRUE; + status = CAIRO_STATUS_SUCCESS; + } + return status; +} + +static cairo_int_status_t +_cairo_analysis_surface_show_glyphs (void *abstract_surface, + cairo_operator_t op, + cairo_pattern_t *source, + const cairo_glyph_t *glyphs, + int num_glyphs, + cairo_scaled_font_t *scaled_font) +{ + cairo_analysis_surface_t *surface = abstract_surface; + cairo_status_t status; + + if (!surface->target->backend->show_glyphs) + status = CAIRO_INT_STATUS_UNSUPPORTED; + else + status = (*surface->target->backend->show_glyphs) (surface->target, op, + source, + glyphs, num_glyphs, + scaled_font); + if (status == CAIRO_INT_STATUS_UNSUPPORTED) { + surface->fallback = TRUE; + status = CAIRO_STATUS_SUCCESS; + } + return status; +} + +static const cairo_surface_backend_t cairo_analysis_surface_backend = { + CAIRO_INTERNAL_SURFACE_TYPE_ANALYSIS, + NULL, /* create_similar */ + NULL, /* finish_surface */ + NULL, /* acquire_source_image */ + NULL, /* release_source_image */ + NULL, /* acquire_dest_image */ + NULL, /* release_dest_image */ + NULL, /* clone_similar */ + NULL, /* composite */ + NULL, /* fill_rectangles */ + NULL, /* composite_trapezoids */ + NULL, /* copy_page */ + NULL, /* show_page */ + NULL, /* set_clip_region */ + NULL, /* clip_path */ + _cairo_analysis_surface_get_extents, + NULL, /* old_show_glyphs */ + NULL, /* get_font_options */ + NULL, /* flush */ + NULL, /* mark_dirty_rectangle */ + NULL, /* scaled_font_fini */ + NULL, /* scaled_glyph_fini */ + _cairo_analysis_surface_paint, + _cairo_analysis_surface_mask, + _cairo_analysis_surface_stroke, + _cairo_analysis_surface_fill, + _cairo_analysis_surface_show_glyphs, + NULL, /* snapshot */ +}; + +cairo_private cairo_surface_t * +_cairo_analysis_surface_create (cairo_surface_t *target, + int width, + int height) +{ + cairo_analysis_surface_t *surface; + + surface = malloc (sizeof (cairo_analysis_surface_t)); + if (surface == NULL) + goto FAIL; + + /* I believe the content type here is truly arbitrary. I'm quite + * sure nothing will ever use this value. */ + _cairo_surface_init (&surface->base, &cairo_analysis_surface_backend, + CAIRO_CONTENT_COLOR_ALPHA); + + surface->width = width; + surface->height = height; + + surface->target = target; + surface->fallback = FALSE; + + return &surface->base; +FAIL: + _cairo_error (CAIRO_STATUS_NO_MEMORY); + return NULL; +} + +cairo_private pixman_region16_t * +_cairo_analysis_surface_get_supported (cairo_surface_t *abstract_surface) +{ + /* XXX */ + return NULL; +} + +cairo_private pixman_region16_t * +_cairo_analysis_surface_get_unsupported (cairo_surface_t *abstract_surface) +{ + /* XXX */ + return NULL; +} + +cairo_private cairo_bool_t +_cairo_analysis_surface_has_unsupported (cairo_surface_t *abstract_surface) +{ + cairo_analysis_surface_t *surface = (cairo_analysis_surface_t *) abstract_surface; + + return surface->fallback; +} + + diff --git a/mozilla/gfx/cairo/cairo/src/cairo-base85-stream.c b/mozilla/gfx/cairo/cairo/src/cairo-base85-stream.c new file mode 100644 index 00000000000..1d4535a9fc0 --- /dev/null +++ b/mozilla/gfx/cairo/cairo/src/cairo-base85-stream.c @@ -0,0 +1,130 @@ +/* cairo_output_stream.c: Output stream abstraction + * + * Copyright © 2005 Red Hat, Inc + * + * This library is free software; you can redistribute it and/or + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. + * + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * The Original Code is cairo_output_stream.c as distributed with the + * cairo graphics library. + * + * The Initial Developer of the Original Code is Red Hat, Inc. + * + * Author(s): + * Kristian Høgsberg + */ + +#include "cairoint.h" + +typedef struct _cairo_base85_stream { + cairo_output_stream_t *output; + unsigned char four_tuple[4]; + int pending; +} cairo_base85_stream_t; + +static void +_expand_four_tuple_to_five (unsigned char four_tuple[4], + unsigned char five_tuple[5], + cairo_bool_t *all_zero) +{ + uint32_t value; + int digit, i; + + value = four_tuple[0] << 24 | four_tuple[1] << 16 | four_tuple[2] << 8 | four_tuple[3]; + if (all_zero) + *all_zero = TRUE; + for (i = 0; i < 5; i++) { + digit = value % 85; + if (digit != 0 && all_zero) + *all_zero = FALSE; + five_tuple[4-i] = digit + 33; + value = value / 85; + } +} + +static cairo_status_t +_cairo_base85_stream_write (void *closure, + const unsigned char *data, + unsigned int length) +{ + cairo_base85_stream_t *stream = closure; + const unsigned char *ptr = data; + unsigned char five_tuple[5]; + cairo_bool_t is_zero; + + while (length) { + stream->four_tuple[stream->pending++] = *ptr++; + length--; + if (stream->pending == 4) { + _expand_four_tuple_to_five (stream->four_tuple, five_tuple, &is_zero); + if (is_zero) + _cairo_output_stream_write (stream->output, "z", 1); + else + _cairo_output_stream_write (stream->output, five_tuple, 5); + stream->pending = 0; + } + } + + return _cairo_output_stream_get_status (stream->output); +} + +static cairo_status_t +_cairo_base85_stream_close (void *closure) +{ + cairo_status_t status; + cairo_base85_stream_t *stream = closure; + unsigned char five_tuple[5]; + + if (stream->pending) { + memset (stream->four_tuple + stream->pending, 0, 4 - stream->pending); + _expand_four_tuple_to_five (stream->four_tuple, five_tuple, NULL); + _cairo_output_stream_write (stream->output, five_tuple, stream->pending + 1); + } + + /* Mark end of base85 data */ + _cairo_output_stream_printf (stream->output, "~>"); + + status = _cairo_output_stream_get_status (stream->output); + + free (stream); + + return status; +} + +cairo_output_stream_t * +_cairo_base85_stream_create (cairo_output_stream_t *output) +{ + cairo_base85_stream_t *stream; + + stream = malloc (sizeof (cairo_base85_stream_t)); + if (stream == NULL) + return (cairo_output_stream_t *) &cairo_output_stream_nil; + + stream->output = output; + stream->pending = 0; + + return _cairo_output_stream_create (_cairo_base85_stream_write, + _cairo_base85_stream_close, + stream); +} + diff --git a/mozilla/gfx/cairo/cairo/src/cairo-operator.c b/mozilla/gfx/cairo/cairo/src/cairo-operator.c new file mode 100644 index 00000000000..99c3aaaa06c --- /dev/null +++ b/mozilla/gfx/cairo/cairo/src/cairo-operator.c @@ -0,0 +1,119 @@ +/* cairo - a vector graphics library with display and print output + * + * Copyright © 2006 Keith Packard + * Copyright © 2006 Red Hat, Inc + * + * This library is free software; you can redistribute it and/or + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. + * + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * The Original Code is the cairo graphics library. + * + * The Initial Developer of the Original Code is University of Southern + * California. + * + * Contributor(s): + * Carl D. Worth + * Keith Packard + */ + +#include "cairoint.h" + +/* The analysis here assumes destination alpha semantics (that is + * CAIRO_CONTENT_COLOR_ALPHA). More things can be considered opaque + * otherwise (CAIRO_CONTENT_COLOR) so we'll probably want to add a + * cairo_content_t parameter to this function + * + * We also need a definition of what "opaque" means. Is it, "does not + * requiring 'knowing' the original contents of destination, nor does + * it set the destination alpha to anything but 1.0" ? + */ +cairo_bool_t +_cairo_operator_always_opaque (cairo_operator_t op) +{ + switch (op) { + case CAIRO_OPERATOR_CLEAR: + return FALSE; + + case CAIRO_OPERATOR_SOURCE: + return FALSE; + + case CAIRO_OPERATOR_OVER: + case CAIRO_OPERATOR_IN: + case CAIRO_OPERATOR_OUT: + case CAIRO_OPERATOR_ATOP: + return FALSE; + + case CAIRO_OPERATOR_DEST: + return TRUE; + + case CAIRO_OPERATOR_DEST_OVER: + case CAIRO_OPERATOR_DEST_IN: + case CAIRO_OPERATOR_DEST_OUT: + case CAIRO_OPERATOR_DEST_ATOP: + return FALSE; + + case CAIRO_OPERATOR_XOR: + case CAIRO_OPERATOR_ADD: + case CAIRO_OPERATOR_SATURATE: + return FALSE; + } + return FALSE; +} + +/* As above, we'll probably want to add a cairo_content_t parameter to + * this function + * + * We also need a definition of what "translucent" means. + */ +cairo_bool_t +_cairo_operator_always_translucent (cairo_operator_t op) +{ + switch (op) { + case CAIRO_OPERATOR_CLEAR: + return TRUE; + + case CAIRO_OPERATOR_SOURCE: + return FALSE; + + case CAIRO_OPERATOR_OVER: + case CAIRO_OPERATOR_IN: + case CAIRO_OPERATOR_OUT: + case CAIRO_OPERATOR_ATOP: + return FALSE; + + case CAIRO_OPERATOR_DEST: + return FALSE; + + case CAIRO_OPERATOR_DEST_OVER: + case CAIRO_OPERATOR_DEST_IN: + case CAIRO_OPERATOR_DEST_OUT: + case CAIRO_OPERATOR_DEST_ATOP: + return FALSE; + + case CAIRO_OPERATOR_XOR: + case CAIRO_OPERATOR_ADD: + case CAIRO_OPERATOR_SATURATE: + return TRUE; + } + return TRUE; +} diff --git a/mozilla/gfx/cairo/cairo/src/cairo-pdf-test.h b/mozilla/gfx/cairo/cairo/src/cairo-pdf-test.h new file mode 100755 index 00000000000..495a4f0e7ca --- /dev/null +++ b/mozilla/gfx/cairo/cairo/src/cairo-pdf-test.h @@ -0,0 +1,76 @@ +/* cairo - a vector graphics library with display and print output + * + * Copyright © 2006 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. + * + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * The Original Code is the cairo graphics library. + * + * The Initial Developer of the Original Code is University of Southern + * California. + * + * Contributor(s): + * Carl D. Worth + */ + +#ifndef CAIRO_PDF_TEST_H +#define CAIRO_PDF_TEST_H + +#include + +#if CAIRO_HAS_PDF_SURFACE + +#include + +CAIRO_BEGIN_DECLS + +struct _cairo_path_fixed; +struct _cairo_traps; +struct _cairo_trapezoid; +struct _cairo_clip; + +void +cairo_pdf_test_force_fallbacks (void); + +void +cairo_debug_dump_clip (struct _cairo_clip *clip, + FILE *fp); +void +cairo_debug_dump_path (struct _cairo_path_fixed *path, + FILE *fp); + +void +cairo_debug_dump_traps (struct _cairo_traps *traps, + FILE *fp); + +void +cairo_debug_dump_trapezoid_array (struct _cairo_trapezoid *traps, + int num_traps, + FILE *fp); + +CAIRO_END_DECLS + +#endif /* CAIRO_HAS_PDF_SURFACE */ +#endif /* CAIRO_PDF_TEST_H */ + diff --git a/mozilla/gfx/cairo/cairo/src/cairo-scaled-font-subsets-private.h b/mozilla/gfx/cairo/cairo/src/cairo-scaled-font-subsets-private.h new file mode 100644 index 00000000000..aed01a306dd --- /dev/null +++ b/mozilla/gfx/cairo/cairo/src/cairo-scaled-font-subsets-private.h @@ -0,0 +1,182 @@ +/* cairo - a vector graphics library with display and print output + * + * Copyright © 2006 Red Hat, Inc + * + * This library is free software; you can redistribute it and/or + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. + * + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * The Original Code is the cairo graphics library. + * + * The Initial Developer of the Original Code is University of Southern + * California. + * + * Contributor(s): + * Carl D. Worth + */ + +#ifndef CAIRO_SCALED_FONT_SUBSETS_PRIVATE_H +#define CAIRO_SCALED_FONT_SUBSETS_PRIVATE_H + +#include "cairoint.h" + +typedef struct _cairo_scaled_font_subsets cairo_scaled_font_subsets_t; + +typedef struct _cairo_scaled_font_subset { + cairo_scaled_font_t *scaled_font; + unsigned int font_id; + unsigned int subset_id; + + /* Index of glyphs array is subset_glyph_index. + * Value of glyphs array is scaled_font_glyph_index. + */ + unsigned long *glyphs; + int num_glyphs; +} cairo_scaled_font_subset_t; + +/** + * _cairo_scaled_font_subsets_create: + * @max_glyphs_per_subset: the maximum number of glyphs that should + * appear in any subset. A value of 0 indicates that there is no limit + * to the number of glyphs per subset. + * + * Create a new #cairo_scaled_font_subsets_t object which can be used + * to create subsets of any number of cairo_scaled_font_t + * objects. This allows the (arbitrarily large and sparse) glyph + * indices of a cairo_scaled_font to be mapped to one or more font + * subsets with glyph indices packed into the range + * [0 .. max_glyphs_per_subset). + * + * Return value: a pointer to the newly creates font subsets. The + * caller owns this object and should call + * _cairo_scaled_font_subsets_destroy() when done with it. + **/ +cairo_private cairo_scaled_font_subsets_t * +_cairo_scaled_font_subsets_create (int max_glyphs_per_subset); + +/** + * _cairo_scaled_font_subsets_destroy: + * @font_subsets: a #cairo_scaled_font_subsets_t object to be destroyed + * + * Destroys @font_subsets and all resources associated with it. + **/ +cairo_private void +_cairo_scaled_font_subsets_destroy (cairo_scaled_font_subsets_t *font_subsets); + +/** + * _cairo_scaled_font_subsets_map_glyph: + * @font_subsets: a #cairo_scaled_font_subsets_t + * @scaled_font: the font of the glyph to be mapped + * @scaled_font_glyph_index: the index of the glyph to be mapped + * @font_id_ret: return value giving the font ID of the mapped glyph + * @subset_id_ret: return value giving the subset ID of the mapped glyph within the @font_id_ret + * @subset_glyph_index_ret: return value giving the index of the mapped glyph within the @subset_id_ret subset + * + * Map a glyph from a #cairo_scaled_font to a new index within a + * subset of that font. The mapping performed is from the tuple: + * + * (scaled_font, scaled_font_glyph_index) + * + * to the tuple: + * + * (font_id, subset_id, subset_glyph_index) + * + * This mapping is 1:1. If the input tuple has previously mapped, the + * the output tuple previously returned will be returned again. + * + * Otherwise, the return tuple will be constructed as follows: + * + * 1) There is a 1:1 correspondence between the input scaled_font + * value and the output font_id value. If no mapping has been + * previously performed with the scaled_font value then the + * smallest unused font_id value will be returned. + * + * 2) Within the set of output tuples of the same font_id value the + * smallest value of subset_id will be returned such that + * subset_glyph_index does not exceed max_glyphs_per_subset (as + * passed to _cairo_scaled_font_subsets_create()) and that the + * resulting tuple is unique. + * + * 3) The smallest value of subset_glyph_index is returned such that + * the resulting tuple is unique. + * + * The net result is that any #cairo_scaled_font_t will be represented + * by one or more font subsets. Each subset is effectively a tuple of + * (scaled_font, font_id, subset_id) and within each subset there + * exists a mapping of scaled_glyph_font_index to subset_glyph_index. + * + * This final description of a font subset is the same representation + * used by #cairo_scaled_font_subset_t as provided by + * _cairo_scaled_font_subsets_foreach. + * + * Return value: CAIRO_STATUS_SUCCESS if successful, or a non-zero + * value indicating an error. Possible errors include + * CAIRO_STATUS_NO_MEMORY. + **/ +cairo_private cairo_status_t +_cairo_scaled_font_subsets_map_glyph (cairo_scaled_font_subsets_t *font_subsets, + cairo_scaled_font_t *scaled_font, + unsigned long scaled_font_glyph_index, + unsigned int *font_id_ret, + unsigned int *subset_id_ret, + unsigned int *subset_glyph_index_ret); + +typedef void +(*cairo_scaled_font_subset_callback_func_t) (cairo_scaled_font_subset_t *font_subset, + void *closure); + +/** + * _cairo_scaled_font_subsets_foreach: + * @font_subsets: a #cairo_scaled_font_subsets_t + * @font_subset_callback: a function to be called for each font subset + * @closure: closure data for the callback function + * + * Iterate over each unique font subset as created by calls to + * _cairo_scaled_font_subsets_map_glyph(). A subset is determined by + * unique pairs of (font_id, subset_id) as returned by + * _cairo_scaled_font_subsets_map_glyph(). + * + * For each subset, @font_subset_callback will be called and will be + * provided with both a #cairo_scaled_font_subset_t object containing + * all the glyphs in the subset as well as the value of @closure. + * + * The #cairo_scaled_font_subset_t object contains the scaled_font, + * the font_id, and the subset_id corresponding to all glyphs + * belonging to the subset. In addition, it contains an array providing + * a mapping between subset glyph indices and the original scaled font + * glyph indices. + * + * The index of the array corresponds to subset_glyph_index values + * returned by _cairo_scaled_font_subsets_map_glyph() while the + * values of the array correspond to the scaled_font_glyph_index + * values passed as input to the same function. + * + * Return value: CAIRO_STATUS_SUCCESS if successful, or a non-zero + * value indicating an error. Possible errors include + * CAIRO_STATUS_NO_MEMORY. + **/ +cairo_private cairo_status_t +_cairo_scaled_font_subsets_foreach (cairo_scaled_font_subsets_t *font_subsets, + cairo_scaled_font_subset_callback_func_t font_subset_callback, + void *closure); + +#endif /* CAIRO_SCALED_FONT_SUBSETS_PRIVATE_H */ diff --git a/mozilla/gfx/cairo/cairo/src/cairo-scaled-font-subsets.c b/mozilla/gfx/cairo/cairo/src/cairo-scaled-font-subsets.c new file mode 100644 index 00000000000..4d8f4bbc3dd --- /dev/null +++ b/mozilla/gfx/cairo/cairo/src/cairo-scaled-font-subsets.c @@ -0,0 +1,385 @@ +/* cairo - a vector graphics library with display and print output + * + * Copyright © 2003 University of Southern California + * Copyright © 2005 Red Hat, Inc + * Copyright © 2006 Keith Packard + * Copyright © 2006 Red Hat, Inc + * + * This library is free software; you can redistribute it and/or + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. + * + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * The Original Code is the cairo graphics library. + * + * The Initial Developer of the Original Code is University of Southern + * California. + * + * Contributor(s): + * Carl D. Worth + * Kristian Høgsberg + * Keith Packard + */ + + +#include "cairoint.h" +#include "cairo-scaled-font-subsets-private.h" + +struct _cairo_scaled_font_subsets { + int max_glyphs_per_subset_limit; + int max_glyphs_per_subset_used; + int num_sub_fonts; + + cairo_hash_table_t *sub_fonts; +}; + +typedef struct _cairo_sub_font { + cairo_hash_entry_t base; + + cairo_scaled_font_subsets_t *parent; + cairo_scaled_font_t *scaled_font; + unsigned int font_id; + + int current_subset; + int num_glyphs_in_current_subset; + int max_glyphs_per_subset; + + cairo_hash_table_t *sub_font_glyphs; +} cairo_sub_font_t; + +typedef struct _cairo_sub_font_glyph { + cairo_hash_entry_t base; + + unsigned int subset_id; + unsigned int subset_glyph_index; +} cairo_sub_font_glyph_t; + +typedef struct _cairo_sub_font_collection { + unsigned long *glyphs; /* scaled_font_glyph_index */ + int glyphs_size; + int max_glyph; + int num_glyphs; + + unsigned int subset_id; + + cairo_scaled_font_subset_callback_func_t font_subset_callback; + void *font_subset_callback_closure; +} cairo_sub_font_collection_t; + +static void +_cairo_sub_font_glyph_init_key (cairo_sub_font_glyph_t *sub_font_glyph, + unsigned long scaled_font_glyph_index) +{ + sub_font_glyph->base.hash = scaled_font_glyph_index; +} + +static cairo_bool_t +_cairo_sub_font_glyphs_equal (const void *key_a, const void *key_b) +{ + const cairo_sub_font_glyph_t *sub_font_glyph_a = key_a; + const cairo_sub_font_glyph_t *sub_font_glyph_b = key_b; + + return sub_font_glyph_a->base.hash == sub_font_glyph_b->base.hash; +} + +static cairo_sub_font_glyph_t * +_cairo_sub_font_glyph_create (unsigned long scaled_font_glyph_index, + unsigned int subset_id, + unsigned int subset_glyph_index) +{ + cairo_sub_font_glyph_t *sub_font_glyph; + + sub_font_glyph = malloc (sizeof (cairo_sub_font_glyph_t)); + if (sub_font_glyph == NULL) + return NULL; + + _cairo_sub_font_glyph_init_key (sub_font_glyph, scaled_font_glyph_index); + sub_font_glyph->subset_id = subset_id; + sub_font_glyph->subset_glyph_index = subset_glyph_index; + + return sub_font_glyph; +} + +static void +_cairo_sub_font_glyph_destroy (cairo_sub_font_glyph_t *sub_font_glyph) +{ + free (sub_font_glyph); +} + +static void +_cairo_sub_font_glyph_pluck (void *entry, void *closure) +{ + cairo_sub_font_glyph_t *sub_font_glyph = entry; + cairo_hash_table_t *sub_font_glyphs = closure; + + _cairo_hash_table_remove (sub_font_glyphs, &sub_font_glyph->base); + _cairo_sub_font_glyph_destroy (sub_font_glyph); +} + +static void +_cairo_sub_font_glyph_collect (void *entry, void *closure) +{ + cairo_sub_font_glyph_t *sub_font_glyph = entry; + cairo_sub_font_collection_t *collection = closure; + unsigned long scaled_font_glyph_index; + unsigned int subset_glyph_index; + + if (sub_font_glyph->subset_id != collection->subset_id) + return; + + scaled_font_glyph_index = sub_font_glyph->base.hash; + subset_glyph_index = sub_font_glyph->subset_glyph_index; + + /* Ensure we don't exceed the allocated bounds. */ + assert (subset_glyph_index < collection->glyphs_size); + + collection->glyphs[subset_glyph_index] = scaled_font_glyph_index; + if (subset_glyph_index > collection->max_glyph) + collection->max_glyph = subset_glyph_index; + + collection->num_glyphs++; +} + +static cairo_bool_t +_cairo_sub_fonts_equal (const void *key_a, const void *key_b) +{ + const cairo_sub_font_t *sub_font_a = key_a; + const cairo_sub_font_t *sub_font_b = key_b; + + return sub_font_a->scaled_font == sub_font_b->scaled_font; +} + +static void +_cairo_sub_font_init_key (cairo_sub_font_t *sub_font, + cairo_scaled_font_t *scaled_font) +{ + sub_font->base.hash = (unsigned long) scaled_font; + sub_font->scaled_font = scaled_font; +} + +static cairo_sub_font_t * +_cairo_sub_font_create (cairo_scaled_font_subsets_t *parent, + cairo_scaled_font_t *scaled_font, + unsigned int font_id, + int max_glyphs_per_subset) +{ + cairo_sub_font_t *sub_font; + + sub_font = malloc (sizeof (cairo_sub_font_t)); + if (sub_font == NULL) + return NULL; + + _cairo_sub_font_init_key (sub_font, scaled_font); + + sub_font->parent = parent; + sub_font->scaled_font = cairo_scaled_font_reference (scaled_font); + sub_font->font_id = font_id; + + sub_font->current_subset = 0; + sub_font->num_glyphs_in_current_subset = 0; + sub_font->max_glyphs_per_subset = max_glyphs_per_subset; + + sub_font->sub_font_glyphs = _cairo_hash_table_create (_cairo_sub_font_glyphs_equal); + if (! sub_font->sub_font_glyphs) { + free (sub_font); + return NULL; + } + + return sub_font; +} + +static void +_cairo_sub_font_destroy (cairo_sub_font_t *sub_font) +{ + _cairo_hash_table_foreach (sub_font->sub_font_glyphs, + _cairo_sub_font_glyph_pluck, + sub_font->sub_font_glyphs); + _cairo_hash_table_destroy (sub_font->sub_font_glyphs); + cairo_scaled_font_destroy (sub_font->scaled_font); + free (sub_font); +} + +static void +_cairo_sub_font_pluck (void *entry, void *closure) +{ + cairo_sub_font_t *sub_font = entry; + cairo_hash_table_t *sub_fonts = closure; + + _cairo_hash_table_remove (sub_fonts, &sub_font->base); + _cairo_sub_font_destroy (sub_font); +} + +static cairo_status_t +_cairo_sub_font_map_glyph (cairo_sub_font_t *sub_font, + unsigned long scaled_font_glyph_index, + unsigned int *subset_id, + unsigned int *subset_glyph_index) +{ + cairo_sub_font_glyph_t key, *sub_font_glyph; + cairo_status_t status; + + _cairo_sub_font_glyph_init_key (&key, scaled_font_glyph_index); + if (! _cairo_hash_table_lookup (sub_font->sub_font_glyphs, &key.base, + (cairo_hash_entry_t **) &sub_font_glyph)) + { + if (sub_font->max_glyphs_per_subset && + sub_font->num_glyphs_in_current_subset == sub_font->max_glyphs_per_subset) + { + sub_font->current_subset++; + sub_font->num_glyphs_in_current_subset = 0; + } + + sub_font_glyph = _cairo_sub_font_glyph_create (scaled_font_glyph_index, + sub_font->current_subset, + sub_font->num_glyphs_in_current_subset++); + if (sub_font_glyph == NULL) + return CAIRO_STATUS_NO_MEMORY; + + if (sub_font->num_glyphs_in_current_subset > sub_font->parent->max_glyphs_per_subset_used) + sub_font->parent->max_glyphs_per_subset_used = sub_font->num_glyphs_in_current_subset; + + status = _cairo_hash_table_insert (sub_font->sub_font_glyphs, &sub_font_glyph->base); + if (status) + return status; + } + + *subset_id = sub_font_glyph->subset_id; + *subset_glyph_index = sub_font_glyph->subset_glyph_index; + + return CAIRO_STATUS_SUCCESS; +} + +static void +_cairo_sub_font_collect (void *entry, void *closure) +{ + cairo_sub_font_t *sub_font = entry; + cairo_sub_font_collection_t *collection = closure; + cairo_scaled_font_subset_t subset; + int i; + + for (i = 0; i <= sub_font->current_subset; i++) { + collection->subset_id = i; + + collection->num_glyphs = 0; + collection->max_glyph = 0; + + _cairo_hash_table_foreach (sub_font->sub_font_glyphs, + _cairo_sub_font_glyph_collect, collection); + + /* Ensure the resulting array has no uninitialized holes */ + assert (collection->num_glyphs == collection->max_glyph + 1); + + subset.scaled_font = sub_font->scaled_font; + subset.font_id = sub_font->font_id; + subset.subset_id = i; + subset.glyphs = collection->glyphs; + subset.num_glyphs = collection->num_glyphs; + + (collection->font_subset_callback) (&subset, + collection->font_subset_callback_closure); + } +} + +cairo_scaled_font_subsets_t * +_cairo_scaled_font_subsets_create (int max_glyphs_per_subset) +{ + cairo_scaled_font_subsets_t *subsets; + + subsets = malloc (sizeof (cairo_scaled_font_subsets_t)); + if (subsets == NULL) + return NULL; + + subsets->max_glyphs_per_subset_limit = max_glyphs_per_subset; + subsets->max_glyphs_per_subset_used = 0; + subsets->num_sub_fonts = 0; + + subsets->sub_fonts = _cairo_hash_table_create (_cairo_sub_fonts_equal); + if (! subsets->sub_fonts) { + free (subsets); + return NULL; + } + + return subsets; +} + +void +_cairo_scaled_font_subsets_destroy (cairo_scaled_font_subsets_t *subsets) +{ + _cairo_hash_table_foreach (subsets->sub_fonts, _cairo_sub_font_pluck, subsets->sub_fonts); + _cairo_hash_table_destroy (subsets->sub_fonts); + free (subsets); +} + +cairo_private cairo_status_t +_cairo_scaled_font_subsets_map_glyph (cairo_scaled_font_subsets_t *subsets, + cairo_scaled_font_t *scaled_font, + unsigned long scaled_font_glyph_index, + unsigned int *font_id, + unsigned int *subset_id, + unsigned int *subset_glyph_index) +{ + cairo_sub_font_t key, *sub_font; + cairo_status_t status; + + _cairo_sub_font_init_key (&key, scaled_font); + if (! _cairo_hash_table_lookup (subsets->sub_fonts, &key.base, + (cairo_hash_entry_t **) &sub_font)) + { + sub_font = _cairo_sub_font_create (subsets, scaled_font, + subsets->num_sub_fonts++, + subsets->max_glyphs_per_subset_limit); + if (sub_font == NULL) + return CAIRO_STATUS_NO_MEMORY; + + status = _cairo_hash_table_insert (subsets->sub_fonts, + &sub_font->base); + if (status) + return status; + } + + *font_id = sub_font->font_id; + + return _cairo_sub_font_map_glyph (sub_font, scaled_font_glyph_index, + subset_id, subset_glyph_index); +} + +cairo_private cairo_status_t +_cairo_scaled_font_subsets_foreach (cairo_scaled_font_subsets_t *font_subsets, + cairo_scaled_font_subset_callback_func_t font_subset_callback, + void *closure) +{ + cairo_sub_font_collection_t collection; + + collection.glyphs_size = font_subsets->max_glyphs_per_subset_used; + collection.glyphs = malloc (collection.glyphs_size * sizeof(unsigned long)); + if (collection.glyphs == NULL) + return CAIRO_STATUS_NO_MEMORY; + + collection.font_subset_callback = font_subset_callback; + collection.font_subset_callback_closure = closure; + + _cairo_hash_table_foreach (font_subsets->sub_fonts, + _cairo_sub_font_collect, &collection); + + free (collection.glyphs); + + return CAIRO_STATUS_SUCCESS; +} diff --git a/mozilla/gfx/thebes/src/nsUnicodeRange.cpp b/mozilla/gfx/thebes/src/nsUnicodeRange.cpp new file mode 100644 index 00000000000..9e30028b4f0 --- /dev/null +++ b/mozilla/gfx/thebes/src/nsUnicodeRange.cpp @@ -0,0 +1,459 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsUnicodeRange.h" + +// This table depends on unicode range definitions. +// Each item's index must correspond unicode range value +// eg. x-cyrillic = LangGroupTable[kRangeCyrillic] +static const char *gUnicodeRangeToLangGroupTable[] = +{ + "x-cyrillic", + "el", + "tr", + "he", + "ar", + "x-baltic", + "th", + "ko", + "ja", + "zh-CN", + "zh-TW", + "x-devanagari", + "x-tamil", + "x-armn", + "x-beng", + "x-cans", + "x-ethi", + "x-geor", + "x-gujr", + "x-guru", + "x-khmr", + "x-mlym" +}; + +/********************************************************************** + * Unicode subranges as defined in unicode 3.0 + * x-western, x-central-euro, tr, x-baltic -> latin + * 0000 - 036f + * 1e00 - 1eff + * 2000 - 206f (general punctuation) + * 20a0 - 20cf (currency symbols) + * 2100 - 214f (letterlike symbols) + * 2150 - 218f (Number Forms) + * el -> greek + * 0370 - 03ff + * 1f00 - 1fff + * x-cyrillic -> cyrillic + * 0400 - 04ff + * he -> hebrew + * 0590 - 05ff + * ar -> arabic + * 0600 - 06ff + * fb50 - fdff (arabic presentation forms) + * fe70 - feff (arabic presentation forms b) + * th - thai + * 0e00 - 0e7f + * ko -> korean + * ac00 - d7af (hangul Syllables) + * 1100 - 11ff (jamo) + * 3130 - 318f (hangul compatibility jamo) + * ja + * 3040 - 309f (hiragana) + * 30a0 - 30ff (katakana) + * zh-CN + * zh-TW + * + * CJK + * 3100 - 312f (bopomofo) + * 31a0 - 31bf (bopomofo extended) + * 3000 - 303f (CJK Symbols and Punctuation) + * 2e80 - 2eff (CJK radicals supplement) + * 2f00 - 2fdf (Kangxi Radicals) + * 2ff0 - 2fff (Ideographic Description Characters) + * 3190 - 319f (kanbun) + * 3200 - 32ff (Enclosed CJK letters and Months) + * 3300 - 33ff (CJK compatibility) + * 3400 - 4dbf (CJK Unified Ideographs Extension A) + * 4e00 - 9faf (CJK Unified Ideographs) + * f900 - fa5f (CJK Compatibility Ideographs) + * fe30 - fe4f (CJK compatibility Forms) + * ff00 - ffef (halfwidth and fullwidth forms) + * + * Armenian + * 0530 - 058f + * Sriac + * 0700 - 074f + * Thaana + * 0780 - 07bf + * Devanagari + * 0900 - 097f + * Bengali + * 0980 - 09ff + * Gurmukhi + * 0a00 - 0a7f + * Gujarati + * 0a80 - 0aff + * Oriya + * 0b00 - 0b7f + * Tamil + * 0b80 - 0bff + * Telugu + * 0c00 - 0c7f + * Kannada + * 0c80 - 0cff + * Malayalam + * 0d00 - 0d7f + * Sinhala + * 0d80 - 0def + * Lao + * 0e80 - 0eff + * Tibetan + * 0f00 - 0fbf + * Myanmar + * 1000 - 109f + * Georgian + * 10a0 - 10ff + * Ethiopic + * 1200 - 137f + * Cherokee + * 13a0 - 13ff + * Canadian Aboriginal Syllabics + * 1400 - 167f + * Ogham + * 1680 - 169f + * Runic + * 16a0 - 16ff + * Khmer + * 1780 - 17ff + * Mongolian + * 1800 - 18af + * Misc - superscripts and subscripts + * 2070 - 209f + * Misc - Combining Diacritical Marks for Symbols + * 20d0 - 20ff + * Misc - Arrows + * 2190 - 21ff + * Misc - Mathematical Operators + * 2200 - 22ff + * Misc - Miscellaneous Technical + * 2300 - 23ff + * Misc - Control picture + * 2400 - 243f + * Misc - Optical character recognition + * 2440 - 2450 + * Misc - Enclose Alphanumerics + * 2460 - 24ff + * Misc - Box Drawing + * 2500 - 257f + * Misc - Block Elements + * 2580 - 259f + * Misc - Geometric Shapes + * 25a0 - 25ff + * Misc - Miscellaneous Symbols + * 2600 - 267f + * Misc - Dingbats + * 2700 - 27bf + * Misc - Braille Patterns + * 2800 - 28ff + * Yi Syllables + * a000 - a48f + * Yi radicals + * a490 - a4cf + * Alphabetic Presentation Forms + * fb00 - fb4f + * Misc - Combining half Marks + * fe20 - fe2f + * Misc - small form variants + * fe50 - fe6f + * Misc - Specials + * fff0 - ffff + *********************************************************************/ + + + +#define NUM_OF_SUBTABLES 9 +#define SUBTABLE_SIZE 16 + +static const PRUint8 gUnicodeSubrangeTable[NUM_OF_SUBTABLES][SUBTABLE_SIZE] = +{ + { // table for X--- + kRangeTableBase+1, //u0xxx + kRangeTableBase+2, //u1xxx + kRangeTableBase+3, //u2xxx + kRangeSetCJK, //u3xxx + kRangeSetCJK, //u4xxx + kRangeSetCJK, //u5xxx + kRangeSetCJK, //u6xxx + kRangeSetCJK, //u7xxx + kRangeSetCJK, //u8xxx + kRangeSetCJK, //u9xxx + kRangeTableBase+4, //uaxxx + kRangeKorean, //ubxxx + kRangeKorean, //ucxxx + kRangeTableBase+5, //udxxx + kRangePrivate, //uexxx + kRangeTableBase+6 //ufxxx + }, + { //table for 0X-- + kRangeSetLatin, //u00xx + kRangeSetLatin, //u01xx + kRangeSetLatin, //u02xx + kRangeGreek, //u03xx XXX 0300-036f is in fact kRangeCombiningDiacriticalMarks + kRangeCyrillic, //u04xx + kRangeTableBase+7, //u05xx, includes Cyrillic supplement, Hebrew, and Armenian + kRangeArabic, //u06xx + kRangeTertiaryTable, //u07xx + kRangeUnassigned, //u08xx + kRangeTertiaryTable, //u09xx + kRangeTertiaryTable, //u0axx + kRangeTertiaryTable, //u0bxx + kRangeTertiaryTable, //u0cxx + kRangeTertiaryTable, //u0dxx + kRangeTertiaryTable, //u0exx + kRangeTibetan, //u0fxx + }, + { //table for 1x-- + kRangeTertiaryTable, //u10xx + kRangeKorean, //u11xx + kRangeEthiopic, //u12xx + kRangeTertiaryTable, //u13xx + kRangeCanadian, //u14xx + kRangeCanadian, //u15xx + kRangeTertiaryTable, //u16xx + kRangeKhmer, //u17xx + kRangeMongolian, //u18xx + kRangeUnassigned, //u19xx + kRangeUnassigned, //u1axx + kRangeUnassigned, //u1bxx + kRangeUnassigned, //u1cxx + kRangeUnassigned, //u1dxx + kRangeSetLatin, //u1exx + kRangeGreek, //u1fxx + }, + { //table for 2x-- + kRangeSetLatin, //u20xx + kRangeSetLatin, //u21xx + kRangeMathOperators, //u22xx + kRangeMiscTechnical, //u23xx + kRangeControlOpticalEnclose, //u24xx + kRangeBoxBlockGeometrics, //u25xx + kRangeMiscSymbols, //u26xx + kRangeDingbats, //u27xx + kRangeBraillePattern, //u28xx + kRangeUnassigned, //u29xx + kRangeUnassigned, //u2axx + kRangeUnassigned, //u2bxx + kRangeUnassigned, //u2cxx + kRangeUnassigned, //u2dxx + kRangeSetCJK, //u2exx + kRangeSetCJK, //u2fxx + }, + { //table for ax-- + kRangeYi, //ua0xx + kRangeYi, //ua1xx + kRangeYi, //ua2xx + kRangeYi, //ua3xx + kRangeYi, //ua4xx + kRangeUnassigned, //ua5xx + kRangeUnassigned, //ua6xx + kRangeUnassigned, //ua7xx + kRangeUnassigned, //ua8xx + kRangeUnassigned, //ua9xx + kRangeUnassigned, //uaaxx + kRangeUnassigned, //uabxx + kRangeKorean, //uacxx + kRangeKorean, //uadxx + kRangeKorean, //uaexx + kRangeKorean, //uafxx + }, + { //table for dx-- + kRangeKorean, //ud0xx + kRangeKorean, //ud1xx + kRangeKorean, //ud2xx + kRangeKorean, //ud3xx + kRangeKorean, //ud4xx + kRangeKorean, //ud5xx + kRangeKorean, //ud6xx + kRangeKorean, //ud7xx + kRangeSurrogate, //ud8xx + kRangeSurrogate, //ud9xx + kRangeSurrogate, //udaxx + kRangeSurrogate, //udbxx + kRangeSurrogate, //udcxx + kRangeSurrogate, //uddxx + kRangeSurrogate, //udexx + kRangeSurrogate, //udfxx + }, + { // table for fx-- + kRangePrivate, //uf0xx + kRangePrivate, //uf1xx + kRangePrivate, //uf2xx + kRangePrivate, //uf3xx + kRangePrivate, //uf4xx + kRangePrivate, //uf5xx + kRangePrivate, //uf6xx + kRangePrivate, //uf7xx + kRangePrivate, //uf8xx + kRangeSetCJK, //uf9xx + kRangeSetCJK, //ufaxx + kRangeArabic, //ufbxx, includes alphabic presentation form + kRangeArabic, //ufcxx + kRangeArabic, //ufdxx + kRangeArabic, //ufexx, includes Combining half marks, + // CJK compatibility forms, + // CJK compatibility forms, + // small form variants + kRangeTableBase+8, //uffxx, halfwidth and fullwidth forms, includes Specials + }, + { //table for 0x0500 - 0x05ff + kRangeCyrillic, //u050x + kRangeCyrillic, //u051x + kRangeCyrillic, //u052x + kRangeArmenian, //u053x + kRangeArmenian, //u054x + kRangeArmenian, //u055x + kRangeArmenian, //u056x + kRangeArmenian, //u057x + kRangeArmenian, //u058x + kRangeHebrew, //u059x + kRangeHebrew, //u05ax + kRangeHebrew, //u05bx + kRangeHebrew, //u05cx + kRangeHebrew, //u05dx + kRangeHebrew, //u05ex + kRangeHebrew, //u05fx + }, + { //table for 0xff00 - 0xffff + kRangeSetCJK, //uff0x, fullwidth latin + kRangeSetCJK, //uff1x, fullwidth latin + kRangeSetCJK, //uff2x, fullwidth latin + kRangeSetCJK, //uff3x, fullwidth latin + kRangeSetCJK, //uff4x, fullwidth latin + kRangeSetCJK, //uff5x, fullwidth latin + kRangeSetCJK, //uff6x, halfwidth katakana + kRangeSetCJK, //uff7x, halfwidth katakana + kRangeSetCJK, //uff8x, halfwidth katakana + kRangeSetCJK, //uff9x, halfwidth katakana + kRangeSetCJK, //uffax, halfwidth hangul jamo + kRangeSetCJK, //uffbx, halfwidth hangul jamo + kRangeSetCJK, //uffcx, halfwidth hangul jamo + kRangeSetCJK, //uffdx, halfwidth hangul jamo + kRangeSetCJK, //uffex, fullwidth symbols + kRangeSpecials, //ufffx, Specials + }, +}; + +// Most scripts between U+0700 and U+16FF are assigned a chunk of 128 (0x80) +// code points so that the number of entries in the tertiary range +// table for that range is obtained by dividing (0x1700 - 0x0700) by 128. +// Exceptions: Ethiopic, Tibetan, Hangul Jamo and Canadian aboriginal +// syllabaries take multiple chunks and Ogham and Runic share a single chunk. +#define TERTIARY_TABLE_SIZE ((0x1700 - 0x0700) / 0x80) + +static const PRUint8 gUnicodeTertiaryRangeTable[TERTIARY_TABLE_SIZE] = +{ //table for 0x0700 - 0x1600 + kRangeSyriac, //u070x + kRangeThaana, //u078x + kRangeUnassigned, //u080x place holder(resolved in the 2ndary tab.) + kRangeUnassigned, //u088x place holder(resolved in the 2ndary tab.) + kRangeDevanagari, //u090x + kRangeBengali, //u098x + kRangeGurmukhi, //u0a0x + kRangeGujarati, //u0a8x + kRangeOriya, //u0b0x + kRangeTamil, //u0b8x + kRangeTelugu, //u0c0x + kRangeKannada, //u0c8x + kRangeMalayalam, //u0d0x + kRangeSinhala, //u0d8x + kRangeThai, //u0e0x + kRangeLao, //u0e8x + kRangeTibetan, //u0f0x place holder(resolved in the 2ndary tab.) + kRangeTibetan, //u0f8x place holder(resolved in the 2ndary tab.) + kRangeMyanmar, //u100x + kRangeGeorgian, //u108x + kRangeKorean, //u110x place holder(resolved in the 2ndary tab.) + kRangeKorean, //u118x place holder(resolved in the 2ndary tab.) + kRangeEthiopic, //u120x place holder(resolved in the 2ndary tab.) + kRangeEthiopic, //u128x place holder(resolved in the 2ndary tab.) + kRangeEthiopic, //u130x + kRangeCherokee, //u138x + kRangeCanadian, //u140x place holder(resolved in the 2ndary tab.) + kRangeCanadian, //u148x place holder(resolved in the 2ndary tab.) + kRangeCanadian, //u150x place holder(resolved in the 2ndary tab.) + kRangeCanadian, //u158x place holder(resolved in the 2ndary tab.) + kRangeCanadian, //u160x + kRangeOghamRunic, //u168x this contains two scripts, Ogham & Runic +}; + +// A two level index is almost enough for locating a range, with the +// exception of u03xx and u05xx. Since we don't really care about range for +// combining diacritical marks in our font application, they are +// not discriminated further. But future adoption of this module for other use +// should be aware of this limitation. The implementation can be extended if +// there is such a need. +// For Indic, Southeast Asian scripts and some other scripts between +// U+0700 and U+16FF, it's extended to the third level. +PRUint32 FindCharUnicodeRange(PRUnichar ch) +{ + PRUint32 range; + + //search the first table + range = gUnicodeSubrangeTable[0][ch >> 12]; + + if (range < kRangeTableBase) + // we try to get a specific range + return range; + + // otherwise, we have one more table to look at + range = gUnicodeSubrangeTable[range - kRangeTableBase][(ch & 0x0f00) >> 8]; + if (range < kRangeTableBase) + return range; + if (range < kRangeTertiaryTable) + return gUnicodeSubrangeTable[range - kRangeTableBase][(ch & 0x00f0) >> 4]; + + // Yet another table to look at : U+0700 - U+16FF : 128 code point blocks + return gUnicodeTertiaryRangeTable[(ch - 0x0700) >> 7]; +} + +const char* LangGroupFromUnicodeRange(PRUint8 unicodeRange) +{ + if (kRangeSpecificItemNum > unicodeRange) + return gUnicodeRangeToLangGroupTable[unicodeRange]; + return nsnull; +} diff --git a/mozilla/gfx/thebes/src/nsUnicodeRange.h b/mozilla/gfx/thebes/src/nsUnicodeRange.h new file mode 100644 index 00000000000..2b98608b4fc --- /dev/null +++ b/mozilla/gfx/thebes/src/nsUnicodeRange.h @@ -0,0 +1,115 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nscore.h" + +// The following constants define unicode subranges +// values below kRangeNum must be continuous so that we can map to +// lang group directly. +// all ranges we care about should be defined under 32, that allows +// us to store range using bits of a PRUint32 + +// frequently used range definitions +const PRUint8 kRangeCyrillic = 0; +const PRUint8 kRangeGreek = 1; +const PRUint8 kRangeTurkish = 2; +const PRUint8 kRangeHebrew = 3; +const PRUint8 kRangeArabic = 4; +const PRUint8 kRangeBaltic = 5; +const PRUint8 kRangeThai = 6; +const PRUint8 kRangeKorean = 7; +const PRUint8 kRangeJapanese = 8; +const PRUint8 kRangeSChinese = 9; +const PRUint8 kRangeTChinese = 10; +const PRUint8 kRangeDevanagari = 11; +const PRUint8 kRangeTamil = 12; +const PRUint8 kRangeArmenian = 13; +const PRUint8 kRangeBengali = 14; +const PRUint8 kRangeCanadian = 15; +const PRUint8 kRangeEthiopic = 16; +const PRUint8 kRangeGeorgian = 17; +const PRUint8 kRangeGujarati = 18; +const PRUint8 kRangeGurmukhi = 19; +const PRUint8 kRangeKhmer = 20; +const PRUint8 kRangeMalayalam = 21; + +const PRUint8 kRangeSpecificItemNum = 22; + +//range/rangeSet grow to this place 22-29 + +const PRUint8 kRangeSetStart = 30; // range set definition starts from here +const PRUint8 kRangeSetLatin = 30; +const PRUint8 kRangeSetCJK = 31; +const PRUint8 kRangeSetEnd = 31; // range set definition ends here + +// less frequently used range definition +const PRUint8 kRangeSurrogate = 32; +const PRUint8 kRangePrivate = 33; +const PRUint8 kRangeMisc = 34; +const PRUint8 kRangeUnassigned = 35; +const PRUint8 kRangeSyriac = 36; +const PRUint8 kRangeThaana = 37; +const PRUint8 kRangeOriya = 38; +const PRUint8 kRangeTelugu = 39; +const PRUint8 kRangeKannada = 40; +const PRUint8 kRangeSinhala = 41; +const PRUint8 kRangeLao = 42; +const PRUint8 kRangeTibetan = 43; +const PRUint8 kRangeMyanmar = 44; +const PRUint8 kRangeCherokee = 45; +const PRUint8 kRangeOghamRunic = 46; +const PRUint8 kRangeMongolian = 47; +const PRUint8 kRangeMathOperators = 48; +const PRUint8 kRangeMiscTechnical = 49; +const PRUint8 kRangeControlOpticalEnclose = 50; +const PRUint8 kRangeBoxBlockGeometrics = 51; +const PRUint8 kRangeMiscSymbols = 52; +const PRUint8 kRangeDingbats = 53; +const PRUint8 kRangeBraillePattern = 54; +const PRUint8 kRangeYi = 55; +const PRUint8 kRangeCombiningDiacriticalMarks = 56; +const PRUint8 kRangeSpecials = 57; + +const PRUint8 kRangeTableBase = 128; //values over 127 are reserved for internal use only +const PRUint8 kRangeTertiaryTable = 145; // leave room for 16 subtable + // indices (kRangeTableBase + 1 .. + // kRangeTableBase + 16) + + + +PRUint32 FindCharUnicodeRange(PRUnichar ch); +const char* LangGroupFromUnicodeRange(PRUint8 unicodeRange); diff --git a/mozilla/layout/html/tests/formctls/bugs/bug300474-1.html b/mozilla/layout/html/tests/formctls/bugs/bug300474-1.html new file mode 100644 index 00000000000..adb88e746dd --- /dev/null +++ b/mozilla/layout/html/tests/formctls/bugs/bug300474-1.html @@ -0,0 +1,31 @@ + + +
+ The buggy display : Select's size attribute is not specified : + +
+
+
+ + What should be displayed : Select's size attribute is forced to 4 : + +
+
+
+ + The width of the widget is also not perfect. +
+ + diff --git a/mozilla/layout/html/tests/formctls/bugs/bug300474-2.html b/mozilla/layout/html/tests/formctls/bugs/bug300474-2.html new file mode 100644 index 00000000000..b83ed7030e5 --- /dev/null +++ b/mozilla/layout/html/tests/formctls/bugs/bug300474-2.html @@ -0,0 +1,531 @@ + + + + Testcase for bug 300474 + + + + +

unspecified size

+ + + + + + + + + + + + + + + + + + + + +
+
+
+

size=0

+ + + + + + + + + + + + + + + + + + +
+
+
+

size=1

+ + + + + + + + + + + + + + + + + + + +
+
+
+

size=4

+ + + + + + + + + + + + + + + + + + + +
+
+
+ +

CSS height:300px

+ + + + + + + + + + + + + + + + + + + + + + diff --git a/mozilla/layout/html/tests/formctls/bugs/bug53259-1.html b/mozilla/layout/html/tests/formctls/bugs/bug53259-1.html new file mode 100644 index 00000000000..fb6d27d1041 --- /dev/null +++ b/mozilla/layout/html/tests/formctls/bugs/bug53259-1.html @@ -0,0 +1,40 @@ +
+ + Div 1: min-width:200px + +
+ +
+ +
+ + Div 2: max-width:200px max-width:200px max-width:200px max-width:200px +max-width:200px + +
+ +
+ +
+ + Div 3: max-width:200px max-width:200px max-width:200px max-width:200px +max-width:200px + +
+ +
+
+ +Div 4: min-width: 50px; max-width: 200px; +
+ + Div 4: + +
+ +
+
+
+<input type=text style="min-width:200px;">
+ +
diff --git a/mozilla/layout/html/tests/formctls/bugs/bug53259-2.html b/mozilla/layout/html/tests/formctls/bugs/bug53259-2.html new file mode 100644 index 00000000000..feaa8b13d3b --- /dev/null +++ b/mozilla/layout/html/tests/formctls/bugs/bug53259-2.html @@ -0,0 +1,24 @@ + + + + +
+
100 pixels width
+
200 pixels width
+
Div with min/max
+
+
+
+
+ + + diff --git a/mozilla/layout/html/tests/formctls/bugs/bug53259-3.html b/mozilla/layout/html/tests/formctls/bugs/bug53259-3.html new file mode 100644 index 00000000000..0b5044e5175 --- /dev/null +++ b/mozilla/layout/html/tests/formctls/bugs/bug53259-3.html @@ -0,0 +1,46 @@ + + + + min-width/max-width on label and inputs + + + + + + +

All the lables (with the red and dashed border) and I should be at least 300px, at most 500px wide.

+ +
This is fixed at 300px wide
+
This is fixed at 500px wide
+ +

+ +

+

+ +

+

+ +

+

+ +

+

+ +

+ + + \ No newline at end of file diff --git a/mozilla/layout/html/tests/formctls/bugs/bug7025-1.html b/mozilla/layout/html/tests/formctls/bugs/bug7025-1.html new file mode 100644 index 00000000000..a3fd519f467 --- /dev/null +++ b/mozilla/layout/html/tests/formctls/bugs/bug7025-1.html @@ -0,0 +1,27 @@ + +Test case for bug #7025 + + +
+Multiple: + + +Not Multiple: + +
+ + diff --git a/mozilla/layout/html/tests/formctls/bugs/bug7025-2.html b/mozilla/layout/html/tests/formctls/bugs/bug7025-2.html new file mode 100644 index 00000000000..4f3ef19eff9 --- /dev/null +++ b/mozilla/layout/html/tests/formctls/bugs/bug7025-2.html @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + +
+ + + +
+ + + + diff --git a/mozilla/mailnews/base/public/nsIMsgTagService.idl b/mozilla/mailnews/base/public/nsIMsgTagService.idl new file mode 100755 index 00000000000..9a47ae1dde9 --- /dev/null +++ b/mozilla/mailnews/base/public/nsIMsgTagService.idl @@ -0,0 +1,72 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * The Mozilla Corporation. + * Portions created by the Initial Developer are Copyright (C) 2006 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * David Bienvenu + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsISupports.idl" +#include "nsIStringEnumerator.idl" + +/* + * Keys are the internal representation of tags, and use a limited range of + * characters, basically the characters allowed in imap keywords, which are + * alphanumeric characters, but don't include spaces. Keys are stored on + * the imap server, in local mail messages, and in summary files. + * + * Tags are the user visible representation of keys, and are full unicode + * strings. Tags should allow any unicode character. + * + * This service will do the mapping between keys and tags. When a tag + * is added, we'll need to "compute" the corresponding key to use. This + * will probably entail replacing illegal ascii characters (' ', '/', etc) + * with '_' and then converting to imap mod utf7. We'll then need to make + * sure that no other keyword has the same value since that algorithm + * doesn't guarantee a unique mapping. + * + */ +[scriptable, uuid(ad04db53-cfcc-47eb-b409-b24b3a0b6130)] +interface nsIMsgTagService : nsISupports { + AString getTagForKey(in ACString key); // look up the tag for a key. + void setTagForKey(in ACString key, in AString tag); // this can be used to "rename" a tag + ACString getKeyForTag(in AString tag); // get the key representation of a given tag + void addTagForKey(in ACString key, in AString tag, in ACString color); + void addTag(in AString tag, in ACString color); + ACString getColorForKey(in ACString key); + void deleteTag(in AString tag); + // we need some way to enumerate all tags. Or return a list of all tags. + readonly attribute nsIStringEnumerator tagEnumerator; + readonly attribute nsIUTF8StringEnumerator keyEnumerator; +}; + diff --git a/mozilla/mailnews/base/resources/content/newTagDialog.js b/mozilla/mailnews/base/resources/content/newTagDialog.js new file mode 100755 index 00000000000..5e631d49600 --- /dev/null +++ b/mozilla/mailnews/base/resources/content/newTagDialog.js @@ -0,0 +1,90 @@ +/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is the new tag dialog + * + * The Initial Developer of the Original Code is + * David Bienvenu. + * Portions created by the Initial Developer are Copyright (C) 2006 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * David Bienvenu + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var dialog; + +function onLoad() +{ + var arguments = window.arguments[0]; + + dialog = {}; + + dialog.OKButton = document.documentElement.getButton("accept"); + + dialog.nameField = document.getElementById("name"); + dialog.nameField.focus(); + + // call this when OK is pressed + dialog.okCallback = arguments.okCallback; + + moveToAlertPosition(); + doEnabling(); +} + +function onOK() +{ + var name = dialog.nameField.value; + + var tagService = Components.classes["@mozilla.org/messenger/tagservice;1"].getService(Components.interfaces.nsIMsgTagService); + // do name validity check? Has to be non-empty, and not existing already + try + { + var key = tagService.getKeyForTag(name); + // above will throw an error if tag doesn't exist. So if it doesn't throw an error, + // the tag exists, so alert the user and return false. + } + catch (ex) {return dialog.okCallback(name, "")} + + var messengerBundle = document.getElementById("bundle_messenger"); + var alertText = messengerBundle.getString("tagExists"); + window.alert(alertText); + return false; +} + +function doEnabling() +{ + if (dialog.nameField.value) { + if (dialog.OKButton.disabled) + dialog.OKButton.disabled = false; + } else { + if (!dialog.OKButton.disabled) + dialog.OKButton.disabled = true; + } +} + diff --git a/mozilla/mailnews/base/resources/content/newTagDialog.xul b/mozilla/mailnews/base/resources/content/newTagDialog.xul new file mode 100755 index 00000000000..7cd7f5e95dc --- /dev/null +++ b/mozilla/mailnews/base/resources/content/newTagDialog.xul @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + +