diff --git a/.cvsignore b/.cvsignore index 845087f..f988935 100644 --- a/.cvsignore +++ b/.cvsignore @@ -1 +1 @@ -xorg-server-20080612.tar.bz2 +xorg-server-1.4.99.906.tar.bz2 diff --git a/sources b/sources index 212093e..ffea069 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -067f2f0fdbcac0f8a7cd4f4ee046a2c8 xorg-server-20080612.tar.bz2 +d225476fea6721d9f64c3268e47d6c51 xorg-server-1.4.99.906.tar.bz2 diff --git a/swrast-dont-abort.patch b/swrast-dont-abort.patch new file mode 100644 index 0000000..7141233 --- /dev/null +++ b/swrast-dont-abort.patch @@ -0,0 +1,92 @@ +From 6bf46df463d19456761ae670f60e0b153e285bd9 Mon Sep 17 00:00:00 2001 +From: Daniel Drake +Date: Thu, 24 Jul 2008 14:42:22 -0400 +Subject: [PATCH] Don't abort if swrast library is not present + +--- + glx/glxdriswrast.c | 6 ++++++ + glx/glxext.c | 37 ++++++++++++++++++++++++------------- + 2 files changed, 30 insertions(+), 13 deletions(-) + +diff --git a/glx/glxdriswrast.c b/glx/glxdriswrast.c +index cf4827e..20c39ab 100644 +--- a/glx/glxdriswrast.c ++++ b/glx/glxdriswrast.c +@@ -468,6 +468,12 @@ __glXDRIscreenProbe(ScreenPtr pScreen) + + screen->driver = dlopen(filename, RTLD_LAZY | RTLD_LOCAL); + if (screen->driver == NULL) { ++ if (errno == ENOENT) { ++ xfree(screen); ++ LogMessage(X_INFO, "AIGLX: swrast library %s not found\n", ++ filename); ++ return NULL; ++ } + LogMessage(X_ERROR, "AIGLX error: dlopen of %s failed (%s)\n", + filename, dlerror()); + goto handle_error; +diff --git a/glx/glxext.c b/glx/glxext.c +index 13c65da..6ba404f 100644 +--- a/glx/glxext.c ++++ b/glx/glxext.c +@@ -279,6 +279,7 @@ void GlxExtensionInit(void) + ScreenPtr pScreen; + int i; + __GLXprovider *p; ++ Bool glx_provided = False; + + __glXContextRes = CreateNewResourceType((DeleteType)ContextGone); + __glXDrawableRes = CreateNewResourceType((DeleteType)DrawableGone); +@@ -289,6 +290,29 @@ void GlxExtensionInit(void) + if (!AddCallback (&ClientStateCallback, glxClientCallback, 0)) + return; + ++ for (i = 0; i < screenInfo.numScreens; i++) { ++ pScreen = screenInfo.screens[i]; ++ ++ for (p = __glXProviderStack; p != NULL; p = p->next) { ++ if (p->screenProbe(pScreen) != NULL) { ++ LogMessage(X_INFO, ++ "GLX: Initialized %s GL provider for screen %d\n", ++ p->name, i); ++ break; ++ } ++ } ++ ++ if (!p) ++ LogMessage(X_INFO, ++ "GLX: no usable GL providers found for screen %d\n", i); ++ else ++ glx_provided = True; ++ } ++ ++ /* don't register extension if GL is not provided on any screen */ ++ if (!glx_provided) ++ return; ++ + /* + ** Add extension to server extensions. + */ +@@ -306,19 +330,6 @@ void GlxExtensionInit(void) + } + + __glXErrorBase = extEntry->errorBase; +- +- for (i = 0; i < screenInfo.numScreens; i++) { +- pScreen = screenInfo.screens[i]; +- +- for (p = __glXProviderStack; p != NULL; p = p->next) { +- if (p->screenProbe(pScreen) != NULL) { +- LogMessage(X_INFO, +- "GLX: Initialized %s GL provider for screen %d\n", +- p->name, i); +- break; +- } +- } +- } + } + + /************************************************************************/ +-- +1.5.5.1 + diff --git a/xorg-x11-server.spec b/xorg-x11-server.spec index eee99b3..5a102bb 100644 --- a/xorg-x11-server.spec +++ b/xorg-x11-server.spec @@ -12,55 +12,50 @@ # F9 TODO list: # # Fix rhpxl to no longer need vesamodes/extramodes -# RHEL5 bugfix sync %define pkgname xorg-server -%define gitdate 20080612 +#define gitdate 20080723 Summary: X.Org X11 X server Name: xorg-x11-server -Version: 1.4.99.902 -Release: 3.%{gitdate}%{?dist}.1 +Version: 1.4.99.906 +Release: 1%{?dist} URL: http://www.x.org License: MIT Group: User Interface/X BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) -%if 0%{gitdate} +%if 0%{?gitdate} # git snapshot. to recreate, run: # ./make-git-snapshot.sh `cat commitid` -Source0: xorg-server-%{gitdate}.tar.bz2 +Source0: xorg-server-%{?gitdate}.tar.bz2 Source1: make-git-snapshot.sh Source2: commitid %else -Source0: ftp://ftp.x.org/pub/individual/xserver/%{pkgname}-%{version}.tar.bz2 +Source0: http://www.x.org/pub/individual/xserver/%{pkgname}-%{version}.tar.bz2 %endif +# Add by OLPC: don't abort if mesa swrast library is not found +Patch1: swrast-dont-abort.patch + # OpenGL compositing manager feature/optimization patches. Patch100: xorg-x11-server-1.1.0-no-move-damage.patch Patch101: xserver-1.4.99-dont-backfill-bg-none.patch # Red Hat specific tweaking, not intended for upstream # XXX move these to the end of the list -Patch1001: xorg-x11-server-Red-Hat-extramodes.patch Patch1003: xserver-1.4.99-pic-libxf86config.patch -Patch1004: xserver-1.4.99-selinux-awareness.patch Patch1005: xserver-1.4.99-builtin-fonts.patch Patch1010: xserver-1.3.0-no-prerelease-warning.patch -Patch1014: xserver-1.4.99-xaa-evict-pixmaps.patch Patch2013: xserver-1.4.99-document-fontpath-correctly.patch # Trivial things to never merge upstream ever -# Don't merge this without protecting the gccisms. -Patch5001: xserver-1.4.99-alloca-poison.patch # This really could be done prettier. Patch5002: xserver-1.4.99-ssh-isnt-local.patch Patch5007: xserver-1.5.0-bad-fbdev-thats-mine.patch -Patch5008: xserver-1.5.0-xaa-sucks.patch #Patch5009: xserver-1.5.0-no-evdev-keyboards-kthnx.patch -Patch5010: xserver-1.5.0-fix-single-aspect.patch %define moduledir %{_libdir}/xorg/modules %define drimoduledir %{_libdir}/dri @@ -99,8 +94,6 @@ BuildRequires: xorg-x11-xtrans-devel >= 1.0.3-3 BuildRequires: libXfont-devel libXau-devel libxkbfile-devel libXres-devel BuildRequires: libfontenc-devel libXtst-devel libXdmcp-devel BuildRequires: libX11-devel libXext-devel -# XXX Really? Why would we need this, Xfont should hide it. -BuildRequires: freetype-devel >= 2.1.9-1 # DMX config utils buildreqs. BuildRequires: libXt-devel libdmx-devel libXmu-devel libXrender-devel @@ -111,8 +104,7 @@ BuildRequires: libXv-devel # openssl? really? BuildRequires: pixman-devel libpciaccess-devel openssl-devel byacc flex -BuildRequires: mesa-libGL-devel >= 7.1-0.21 -BuildRequires: mesa-source >= 7.1-0.21 +BuildRequires: mesa-libGL-devel >= 7.1-0.36 # XXX silly... BuildRequires: libdrm-devel >= 2.4.0 %if %{with_hw_servers} @@ -122,17 +114,6 @@ Requires: libdrm >= 2.4.0 BuildRequires: audit-libs-devel libselinux-devel >= 2.0.59-1 BuildRequires: hal-devel dbus-devel -# Make sure libXfont has the catalogue FPE -Conflicts: libXfont < 1.2.9 - -# Make sure we pull ABI compatible drivers. -Conflicts: xorg-x11-drv-ati < 6.6.1 -Conflicts: xorg-x11-drv-i810 < 1.6.0 -# Match up work-arounds between compiz and the xserver -Conflicts: compiz < 0.0.13-0.20.20060817git.fc6 -# Match up GLX_EXT_texture_from_pixmap opcodes -Conflicts: mesa-libGL < 6.5.1-2.fc6 - # All server subpackages have a virtual provide for the name of the server # they deliver. The Xorg one is versioned, the others are intentionally # unversioned. @@ -185,10 +166,7 @@ Provides: Xnest %description Xnest Xnest is an X server, which has been implemented as an ordinary X application. It runs in a window just like other X applications, -but it is an X server itself in which you can run other software. It -is a very useful tool for developers who wish to test their -applications without running them on their real X server. - +but it is an X server itself in which you can run other software. %package Xdmx Summary: Distributed Multihead X Server and utilities @@ -201,12 +179,7 @@ Provides: Xdmx Xdmx is proxy X server that provides multi-head support for multiple displays attached to different machines (each of which is running a typical X server). When Xinerama is used with Xdmx, the multiple displays on multiple machines -are presented to the user as a single unified screen. A simple application -for Xdmx would be to provide multi-head support using two desktop machines, -each of which has a single display device attached to it. A complex -application for Xdmx would be to unify a 4 by 4 grid of 1280x1024 displays -(each attached to one of 16 computers) into a unified 5120x4096 display. - +are presented to the user as a single unified screen. %package Xvfb Summary: A X Windows System virtual framebuffer X server. @@ -232,10 +205,8 @@ Provides: Xephyr %description Xephyr Xephyr is an X server, which has been implemented as an ordinary X application. It runs in a window just like other X applications, -but it is an X server itself in which you can run other software. It -is a very useful tool for developers who wish to test their -applications without running them on their real X server. Unlike -Xnest, Xephyr renders to an X image rather than relaying the +but it is an X server itself in which you can run other software. +Unlike Xnest, Xephyr renders to an X image rather than relaying the X protocol, and therefore supports the newer X extensions like Render and Composite. @@ -270,21 +241,20 @@ Xserver source code needed to build VNC server (Xvnc) %prep %setup -q -n %{pkgname}-%{?gitdate:%{gitdate}}%{!?gitdate:%{version}} -%if 0%{gitdate} +%if 0%{?gitdate} # XXX hack git checkout -b fedora # make it something you can push to. sed -i 's/git/&+ssh/' .git/config %else git-init-db -echo "This is incomplete. FIXME." -exit 1 -%endif - if [ -z "$GIT_COMMITTER_NAME" ]; then - export GIT_COMMITTER_NAME="Fedora X Ninjas" + git-config user.email "x@fedoraproject.org" + git-config user.name "Fedora X Ninjas" fi - +git-add . +git-commit -a -q -m "%{version} baseline." +%endif # Apply all the patches. Hold your nose... git-am -p1 $(awk '/^Patch.*:/ { print "%{_sourcedir}/"$2 }' %{_specdir}/%{name}.spec) @@ -308,9 +278,8 @@ export CFLAGS="${RPM_OPT_FLAGS} -Wstrict-overflow" --with-xkb-output=%{_localstatedir}/lib/xkb \ --with-rgb-path=%{_datadir}/X11/rgb \ --disable-xorgcfg \ - --disable-record \ + --disable-record --disable-xtrap \ --enable-install-libxf86config \ - --with-mesa-source=%{_datadir}/mesa/source \ --enable-xselinux \ --with-dri-driver-path=%{drimoduledir} \ ${CONFIGURE} @@ -336,7 +305,6 @@ install -m 0444 hw/xfree86/common/{vesa,extra}modes $RPM_BUILD_ROOT%{_datadir}/x mkdir -p %{inst_srcdir}/{Xext,xkb,GL,hw/xfree86/{common,utils/xorgconfig}} cp cpprules.in %{inst_srcdir} cp xkb/README.compiled %{inst_srcdir}/xkb -cp GL/symlink-mesa.sh %{inst_srcdir}/GL cp hw/xfree86/{xorgconf.cpp,Options} %{inst_srcdir}/hw/xfree86 cp hw/xfree86/common/{vesamodes,extramodes} %{inst_srcdir}/hw/xfree86/common cp hw/xfree86/utils/xorgconfig/Cards{,98} %{inst_srcdir}/hw/xfree86/utils/xorgconfig/ @@ -356,21 +324,6 @@ xargs tar cf - | (cd %{inst_srcdir} && tar xf -) rm -f $RPM_BUILD_ROOT%{_bindir}/pcitweak rm -f $RPM_BUILD_ROOT%{_mandir}/man1/pcitweak.1* find $RPM_BUILD_ROOT -type f -name '*.la' | xargs rm -f -- || : - -%if !%{with_hw_servers} - # These get installed regardless of whether you're building Xorg. - # XXX Re-check this list. - # error: Installed (but unpackaged) file(s) found: - # /randrstr.h - # /usr/lib/pkgconfig/xorg-server.pc - # /usr/share/aclocal/xorg-server.m4 - # /var/lib/xkb/README.compiled - - rm -f $RPM_BUILD_ROOT/randrstr.h - rm -rf $RPM_BUILD_ROOT%{_libdir}/pkgconfig - rm -rf $RPM_BUILD_ROOT%{_datadir}/aclocal - rm -rf $RPM_BUILD_ROOT/var/lib/xkb -%endif } %clean @@ -418,13 +371,11 @@ rm -rf $RPM_BUILD_ROOT %dir %{_libdir}/xorg/modules %dir %{_libdir}/xorg/modules/drivers %dir %{_libdir}/xorg/modules/extensions -%{_libdir}/xorg/modules/extensions/libGLcore.so %{_libdir}/xorg/modules/extensions/libglx.so %{_libdir}/xorg/modules/extensions/libdri.so %{_libdir}/xorg/modules/extensions/libdri2.so %{_libdir}/xorg/modules/extensions/libdbe.so %{_libdir}/xorg/modules/extensions/libextmod.so -%{_libdir}/xorg/modules/extensions/libxtrap.so %dir %{_libdir}/xorg/modules/input %dir %{_libdir}/xorg/modules/fonts %{_libdir}/xorg/modules/fonts/libfreetype.so @@ -511,6 +462,10 @@ rm -rf $RPM_BUILD_ROOT %changelog +* Thu Jul 24 2008 Daniel Drake 1.4.99.906-1 +- resync with F-9 for new xinput ABI +- add patch to allow X server to run when mesa's swrast is not present + * Tue Jun 17 2008 Dennis Gilmore 1.4.99.902-3.20080612.1 - disable the noevdev patch for OLPC diff --git a/xserver-1.4.99-selinux-awareness.patch b/xserver-1.4.99-selinux-awareness.patch deleted file mode 100644 index 3b8ba19..0000000 --- a/xserver-1.4.99-selinux-awareness.patch +++ /dev/null @@ -1,48 +0,0 @@ -From d4112defb9ab2b099c67a0a7c2ae7ac772d67751 Mon Sep 17 00:00:00 2001 -From: Adam Jackson -Date: Mon, 7 Jan 2008 15:41:22 -0500 -Subject: [PATCH] Link GL subsystem against libselinux. - ---- - configure.ac | 4 +++- - hw/xfree86/dixmods/Makefile.am | 2 +- - 2 files changed, 4 insertions(+), 2 deletions(-) - -diff --git a/configure.ac b/configure.ac -index 0742040..ed6d062 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -360,6 +360,8 @@ case $host_cpu in - esac - AC_SUBST(GLX_ARCH_DEFINES) - -+SYS_LIBS="${SYS_LIBS} -lselinux" -+ - dnl BSD *_video.c selection - AM_CONDITIONAL(ALPHA_VIDEO, [test "x$ALPHA_VIDEO" = xyes]) - AM_CONDITIONAL(ARM_VIDEO, [test "x$ARM_VIDEO" = xyes]) -@@ -1211,7 +1213,7 @@ AC_MSG_RESULT([$XNEST]) - AM_CONDITIONAL(XNEST, [test "x$XNEST" = xyes]) - - if test "x$XNEST" = xyes; then -- XNEST_LIBS="$FB_LIB $FIXES_LIB $MI_LIB $XEXT_LIB $DBE_LIB $XTRAP_LIB $RECORD_LIB $GLX_LIBS $RENDER_LIB $RANDR_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $XPSTUBS_LIB $DIX_LIB $OS_LIB $CONFIG_LIB" -+ XNEST_LIBS="$FB_LIB $FIXES_LIB $MI_LIB $XEXT_LIB $DBE_LIB $XTRAP_LIB $RECORD_LIB $GLX_LIBS $RENDER_LIB $RANDR_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $XPSTUBS_LIB $DIX_LIB $OS_LIB $CONFIG_LIB $XSERVER_LIBS" - XNEST_SYS_LIBS="$XNESTMODULES_LIBS" - AC_SUBST([XNEST_LIBS]) - AC_SUBST([XNEST_SYS_LIBS]) -diff --git a/hw/xfree86/dixmods/Makefile.am b/hw/xfree86/dixmods/Makefile.am -index efc5f4a..1b9ecfd 100644 ---- a/hw/xfree86/dixmods/Makefile.am -+++ b/hw/xfree86/dixmods/Makefile.am -@@ -50,7 +50,7 @@ INCLUDES = @XORG_INCS@ \ - -I$(top_srcdir)/GL/glx - - libGLcore_la_LDFLAGS = -avoid-version --libGLcore_la_LIBADD = $(top_builddir)/GL/mesa/libGLcore.la -+libGLcore_la_LIBADD = $(top_builddir)/GL/mesa/libGLcore.la -lselinux - libGLcore_la_SOURCES = GLcoremodule.c - - libafb_la_LDFLAGS = -avoid-version --- -1.5.3.7 - diff --git a/xserver-1.4.99-xaa-evict-pixmaps.patch b/xserver-1.4.99-xaa-evict-pixmaps.patch deleted file mode 100644 index edf099b..0000000 --- a/xserver-1.4.99-xaa-evict-pixmaps.patch +++ /dev/null @@ -1,78 +0,0 @@ -From fb3008787193b79909fe922577794f7d4a656922 Mon Sep 17 00:00:00 2001 -From: Adam Jackson -Date: Thu, 1 Nov 2007 15:18:31 -0400 -Subject: [PATCH] Add pixmap eviction call for XAA. - -DRI drivers without zero-copy EXT_texture_from_pixmap need to copy the -texture image out of video memory to bind it. Ick. Add a hack to -evict XAA pixmaps and disable the pixmap cache when the first texture -is bound. ---- - GL/glx/glxdri.c | 16 ++++++++++++++++ - hw/xfree86/xaa/xaaInit.c | 24 ++++++++++++++++++++++++ - 2 files changed, 40 insertions(+), 0 deletions(-) - -diff --git a/GL/glx/glxdri.c b/GL/glx/glxdri.c -index c0da07b..6c4faed 100644 ---- a/GL/glx/glxdri.c -+++ b/GL/glx/glxdri.c -@@ -360,6 +360,22 @@ - - pixmap = (PixmapPtr) glxPixmap->pDraw; - -+ if (!screen->texOffsetStart) { -+ /* When the GLX_EXT_texture_from_pixmap is used, as it's -+ * implemented here, we want to pull pixmap out of video memory -+ * and into host memory. */ -+ extern void XAAEvictPixmaps(void); -+ static int evictedPixmaps = 0; -+ -+ if (!evictedPixmaps) { -+ __glXDRIenterServer(GL_FALSE); -+ if (dlsym(RTLD_DEFAULT, "XAAEvictPixmaps")) -+ XAAEvictPixmaps(); -+ __glXDRIleaveServer(GL_FALSE); -+ evictedPixmaps = TRUE; -+ } -+ } -+ - if (screen->texOffsetStart && screen->texOffset) { - __GLXDRIdrawable **texOffsetOverride = screen->texOffsetOverride; - int i, firstEmpty = 16; -diff --git a/hw/xfree86/xaa/xaaInit.c b/hw/xfree86/xaa/xaaInit.c ---- a/hw/xfree86/xaa/xaaInit.c -+++ b/hw/xfree86/xaa/xaaInit.c -@@ -88,6 +88,30 @@ - xfree(infoRec); - } - -+void -+XAAEvictPixmaps(void) -+{ -+ XAAScreenPtr pScreenPriv; -+ XAAInfoRecPtr infoRec; -+ ScreenPtr pScreen; -+ int i; -+ -+ xf86MsgVerb(X_INFO, 3, "XAA: Evicting pixmaps\n"); -+ -+ for (i = 0; i < screenInfo.numScreens; i++) { -+ pScreen = screenInfo.screens[i]; -+ infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen); -+ -+ pScreenPriv = dixLookupPrivate(&pScreen->devPrivates, XAAScreenKey); -+ infoRec = pScreenPriv->AccelInfoRec; -+ -+ infoRec->offscreenDepths = 0; -+ infoRec->Flags &= ~OFFSCREEN_PIXMAPS; -+ -+ XAAMoveOutOffscreenPixmaps(pScreen); -+ XAAInvalidatePixmapCache(pScreen); -+ } -+} - - Bool - XAAInit(ScreenPtr pScreen, XAAInfoRecPtr infoRec) --- -1.5.3.4 - diff --git a/xserver-1.5.0-xaa-sucks.patch b/xserver-1.5.0-xaa-sucks.patch deleted file mode 100644 index 8b17791..0000000 --- a/xserver-1.5.0-xaa-sucks.patch +++ /dev/null @@ -1,46 +0,0 @@ -From a01ca030c7a1f38e411281d888f0acf2c3fb40f3 Mon Sep 17 00:00:00 2001 -From: Adam Jackson -Date: Thu, 13 Mar 2008 13:38:02 -0400 -Subject: [PATCH] Disable XAA offscreen pixmaps by default. - -Say Option "XaaOffscreenPixmaps" to turn them back on. ---- - hw/xfree86/xaa/xaaInitAccel.c | 8 ++++++-- - 1 files changed, 6 insertions(+), 2 deletions(-) - -diff --git a/hw/xfree86/xaa/xaaInitAccel.c b/hw/xfree86/xaa/xaaInitAccel.c -index 1b7c154..f3c8f56 100644 ---- a/hw/xfree86/xaa/xaaInitAccel.c -+++ b/hw/xfree86/xaa/xaaInitAccel.c -@@ -43,7 +43,8 @@ typedef enum { - XAAOPT_WRITE_BITMAP, - XAAOPT_WRITE_PIXMAP, - XAAOPT_PIXMAP_CACHE, -- XAAOPT_OFFSCREEN_PIXMAPS -+ XAAOPT_OFFSCREEN_PIXMAPS, -+ XAAOPT_HAS_DUMB_INVERTED_OPTION_SENSE - } XAAOpts; - - static const OptionInfoRec XAAOptions[] = { -@@ -89,6 +90,8 @@ static const OptionInfoRec XAAOptions[] = { - OPTV_BOOLEAN, {0}, FALSE }, - {XAAOPT_OFFSCREEN_PIXMAPS, "XaaNoOffscreenPixmaps", - OPTV_BOOLEAN, {0}, FALSE }, -+ {XAAOPT_HAS_DUMB_INVERTED_OPTION_SENSE, "XaaOffscreenPixmaps", -+ OPTV_BOOLEAN, {0}, FALSE }, - { -1, NULL, - OPTV_NONE, {0}, FALSE } - }; -@@ -532,8 +532,8 @@ XAAInitAccel(ScreenPtr pScreen, XAAInfoRecPtr infoRec) - #define XAAMSG(s) do { if (serverGeneration == 1) xf86ErrorF(s); } while (0) - - if((infoRec->Flags & OFFSCREEN_PIXMAPS) && HaveScreenToScreenCopy && -- !xf86ReturnOptValBool(options, XAAOPT_OFFSCREEN_PIXMAPS, -- FALSE)) { -+ xf86IsOptionSet(options, XAAOPT_HAS_DUMB_INVERTED_OPTION_SENSE)) -+ { - XAAMSG("\tOffscreen Pixmaps\n"); - } else { - infoRec->Flags &= ~OFFSCREEN_PIXMAPS; --- -1.5.4.3