From 2bc52b2ec7c27a4269bf437e564164d6c4ccd8ec Mon Sep 17 00:00:00 2001 From: Chris Lord Date: Fri, 19 Aug 2011 09:36:04 +0100 Subject: [PATCH 01/71] Bug 675908 - Fix TiledTextureImage updates. r=joe,romaxa TiledTextureImage breaks BeginUpdate/EndUpdate in these cases: - The update is encompassed by more than one tile - The update is encompassed by a single tile that isn't the first tile - The update is a non-rectangular region that covers more than one tile Fixed by using signed instead of unsigned integers in tile loops, correcting an incorrect device offset and correcting the region returned by BeginUpdate. --- gfx/thebes/GLContext.cpp | 109 +++++++++++++++++++++------- gfx/thebes/GLContext.h | 11 +++ gfx/thebes/GLContextProviderEGL.cpp | 33 +++++---- 3 files changed, 109 insertions(+), 44 deletions(-) diff --git a/gfx/thebes/GLContext.cpp b/gfx/thebes/GLContext.cpp index fcf78f30db32..4611ad5ef8ce 100644 --- a/gfx/thebes/GLContext.cpp +++ b/gfx/thebes/GLContext.cpp @@ -575,20 +575,8 @@ BasicTextureImage::BeginUpdate(nsIntRegion& aRegion) NS_ASSERTION(!mUpdateSurface, "BeginUpdate() without EndUpdate()?"); // determine the region the client will need to repaint - ImageFormat format = - (GetContentType() == gfxASurface::CONTENT_COLOR) ? - gfxASurface::ImageFormatRGB24 : gfxASurface::ImageFormatARGB32; - if (mTextureState != Valid) - { - // if the texture hasn't been initialized yet, or something important - // changed, we need to recreate our backing surface and force the - // client to paint everything - mUpdateRegion = nsIntRect(nsIntPoint(0, 0), mSize); - } else { - mUpdateRegion = aRegion; - } - - aRegion = mUpdateRegion; + GetUpdateRegion(aRegion); + mUpdateRegion = aRegion; nsIntRect rgnSize = mUpdateRegion.GetBounds(); if (!nsIntRect(nsIntPoint(0, 0), mSize).Contains(rgnSize)) { @@ -596,7 +584,10 @@ BasicTextureImage::BeginUpdate(nsIntRegion& aRegion) return NULL; } - mUpdateSurface = + ImageFormat format = + (GetContentType() == gfxASurface::CONTENT_COLOR) ? + gfxASurface::ImageFormatRGB24 : gfxASurface::ImageFormatARGB32; + mUpdateSurface = GetSurfaceForUpdate(gfxIntSize(rgnSize.width, rgnSize.height), format); if (!mUpdateSurface || mUpdateSurface->CairoStatus()) { @@ -609,6 +600,16 @@ BasicTextureImage::BeginUpdate(nsIntRegion& aRegion) return mUpdateSurface; } +void +BasicTextureImage::GetUpdateRegion(nsIntRegion& aForRegion) +{ + // if the texture hasn't been initialized yet, or something important + // changed, we need to recreate our backing surface and force the + // client to paint everything + if (mTextureState != Valid) + aForRegion = nsIntRect(nsIntPoint(0, 0), mSize); +} + void BasicTextureImage::EndUpdate() { @@ -729,10 +730,9 @@ TiledTextureImage::~TiledTextureImage() bool TiledTextureImage::DirectUpdate(gfxASurface* aSurf, const nsIntRegion& aRegion, const nsIntPoint& aFrom /* = nsIntPoint(0, 0) */) { - nsIntRect bounds = aRegion.GetBounds(); nsIntRegion region; if (mTextureState != Valid) { - bounds = nsIntRect(0, 0, mSize.width, mSize.height); + nsIntRect bounds = nsIntRect(0, 0, mSize.width, mSize.height); region = nsIntRegion(bounds); } else { region = aRegion; @@ -740,8 +740,8 @@ TiledTextureImage::DirectUpdate(gfxASurface* aSurf, const nsIntRegion& aRegion, PRBool result = PR_TRUE; for (unsigned i = 0; i < mImages.Length(); i++) { - unsigned int xPos = (i % mColumns) * mTileSize; - unsigned int yPos = (i / mColumns) * mTileSize; + int xPos = (i % mColumns) * mTileSize; + int yPos = (i / mColumns) * mTileSize; nsIntRegion tileRegion; tileRegion.And(region, nsIntRect(nsIntPoint(xPos,yPos), mImages[i]->GetSize())); // intersect with tile if (tileRegion.IsEmpty()) @@ -757,25 +757,66 @@ TiledTextureImage::DirectUpdate(gfxASurface* aSurf, const nsIntRegion& aRegion, return result; } +void +TiledTextureImage::GetUpdateRegion(nsIntRegion& aForRegion) +{ + if (mTextureState != Valid) { + // if the texture hasn't been initialized yet, or something important + // changed, we need to recreate our backing surface and force the + // client to paint everything + aForRegion = nsIntRect(nsIntPoint(0, 0), mSize); + return; + } + + nsIntRegion newRegion; + + // We need to query each texture with the region it will be drawing and + // set aForRegion to be the combination of all of these regions + for (unsigned i = 0; i < mImages.Length(); i++) { + int xPos = (i % mColumns) * mTileSize; + int yPos = (i / mColumns) * mTileSize; + nsIntRect imageRect = nsIntRect(nsIntRect(nsIntPoint(xPos,yPos), mImages[i]->GetSize())); + + if (aForRegion.Intersects(imageRect)) { + // Make a copy of the region + nsIntRegion subRegion; + subRegion.And(aForRegion, imageRect); + // Translate it into tile-space + subRegion.MoveBy(-xPos, -yPos); + // Query region + mImages[i]->GetUpdateRegion(subRegion); + // Translate back + subRegion.MoveBy(xPos, yPos); + // Add to the accumulated region + newRegion.Or(newRegion, subRegion); + } + } + + aForRegion = newRegion; +} + gfxASurface* TiledTextureImage::BeginUpdate(nsIntRegion& aRegion) { NS_ASSERTION(!mInUpdate, "nested update"); mInUpdate = PR_TRUE; + // Note, we don't call GetUpdateRegion here as if the updated region is + // fully contained in a single tile, we get to avoid iterating through + // the tiles again (and a little copying). if (mTextureState != Valid) { // if the texture hasn't been initialized yet, or something important // changed, we need to recreate our backing surface and force the // client to paint everything - mUpdateRegion = nsIntRect(nsIntPoint(0, 0), mSize); - } else { - mUpdateRegion = aRegion; + aRegion = nsIntRect(nsIntPoint(0, 0), mSize); } + nsIntRect bounds = aRegion.GetBounds(); + for (unsigned i = 0; i < mImages.Length(); i++) { - unsigned int xPos = (i % mColumns) * mTileSize; - unsigned int yPos = (i / mColumns) * mTileSize; + int xPos = (i % mColumns) * mTileSize; + int yPos = (i / mColumns) * mTileSize; nsIntRegion imageRegion = nsIntRegion(nsIntRect(nsIntPoint(xPos,yPos), mImages[i]->GetSize())); // a single Image can handle this update request @@ -786,6 +827,10 @@ TiledTextureImage::BeginUpdate(nsIntRegion& aRegion) nsRefPtr surface = mImages[i]->BeginUpdate(aRegion); // caller expects container space aRegion.MoveBy(xPos, yPos); + // Correct the device offset + gfxPoint offset = surface->GetDeviceOffset(); + surface->SetDeviceOffset(gfxPoint(offset.x - xPos, + offset.y - yPos)); // we don't have a temp surface mUpdateSurface = nsnull; // remember which image to EndUpdate @@ -793,15 +838,21 @@ TiledTextureImage::BeginUpdate(nsIntRegion& aRegion) return surface.get(); } } + + // Get the real updated region, taking into account the capabilities of + // each TextureImage tile + GetUpdateRegion(aRegion); + mUpdateRegion = aRegion; + bounds = aRegion.GetBounds(); + // update covers multiple Images - create a temp surface to paint in gfxASurface::gfxImageFormat format = (GetContentType() == gfxASurface::CONTENT_COLOR) ? gfxASurface::ImageFormatRGB24 : gfxASurface::ImageFormatARGB32; - - nsIntRect bounds = aRegion.GetBounds(); mUpdateSurface = gfxPlatform::GetPlatform()-> CreateOffscreenSurface(gfxIntSize(bounds.width, bounds.height), gfxASurface::ContentFromFormat(format)); mUpdateSurface->SetDeviceOffset(gfxPoint(-bounds.x, -bounds.y)); + return mUpdateSurface; } @@ -820,9 +871,10 @@ TiledTextureImage::EndUpdate() // upload tiles from temp surface for (unsigned i = 0; i < mImages.Length(); i++) { - unsigned int xPos = (i % mColumns) * mTileSize; - unsigned int yPos = (i / mColumns) * mTileSize; + int xPos = (i % mColumns) * mTileSize; + int yPos = (i / mColumns) * mTileSize; nsIntRect imageRect = nsIntRect(nsIntPoint(xPos,yPos), mImages[i]->GetSize()); + nsIntRegion subregion; subregion.And(mUpdateRegion, imageRect); if (subregion.IsEmpty()) @@ -842,6 +894,7 @@ TiledTextureImage::EndUpdate() mInUpdate = PR_FALSE; mShaderType = mImages[0]->GetShaderProgramType(); mIsRGBFormat = mImages[0]->IsRGB(); + mTextureState = Valid; } void TiledTextureImage::BeginTileIteration() diff --git a/gfx/thebes/GLContext.h b/gfx/thebes/GLContext.h index 6114a438e8cb..4428690e4c09 100644 --- a/gfx/thebes/GLContext.h +++ b/gfx/thebes/GLContext.h @@ -193,6 +193,15 @@ public: * followed by EndUpdate(). */ virtual gfxASurface* BeginUpdate(nsIntRegion& aRegion) = 0; + /** + * Retrieves the region that will require updating, given a + * region that needs to be updated. This can be used for + * making decisions about updating before calling BeginUpdate(). + * + * |aRegion| is an inout param. + */ + virtual void GetUpdateRegion(nsIntRegion& aForRegion) { + }; /** * Finish the active update and synchronize with the server, if * necessary. @@ -348,6 +357,7 @@ public: virtual void BindTexture(GLenum aTextureUnit); virtual gfxASurface* BeginUpdate(nsIntRegion& aRegion); + virtual void GetUpdateRegion(nsIntRegion& aForRegion); virtual void EndUpdate(); virtual bool DirectUpdate(gfxASurface* aSurf, const nsIntRegion& aRegion, const nsIntPoint& aFrom = nsIntPoint(0,0)); virtual GLuint GetTextureID() { return mTexture; }; @@ -392,6 +402,7 @@ public: ~TiledTextureImage(); void DumpDiv(); virtual gfxASurface* BeginUpdate(nsIntRegion& aRegion); + virtual void GetUpdateRegion(nsIntRegion& aForRegion); virtual void EndUpdate(); virtual void Resize(const nsIntSize& aSize); virtual void BeginTileIteration(); diff --git a/gfx/thebes/GLContextProviderEGL.cpp b/gfx/thebes/GLContextProviderEGL.cpp index b3251fd9ea88..3594229d27fd 100644 --- a/gfx/thebes/GLContextProviderEGL.cpp +++ b/gfx/thebes/GLContextProviderEGL.cpp @@ -1207,27 +1207,28 @@ public: } } + virtual void GetUpdateRegion(nsIntRegion& aForRegion) + { + if (mTextureState != Valid) { + // if the texture hasn't been initialized yet, force the + // client to paint everything + aForRegion = nsIntRect(nsIntPoint(0, 0), mSize); + } else if (!mBackingSurface) { + // We can only draw a rectangle, not subregions due to + // the way that our texture upload functions work. If + // needed, we /could/ do multiple texture uploads if we have + // non-overlapping rects, but that's a tradeoff. + aForRegion = nsIntRegion(mUpdateRect); + } + } + virtual gfxASurface* BeginUpdate(nsIntRegion& aRegion) { NS_ASSERTION(!mUpdateSurface, "BeginUpdate() without EndUpdate()?"); // determine the region the client will need to repaint - if (mTextureState != Valid) { - // if the texture hasn't been initialized yet, force the - // client to paint everything - mUpdateRect = nsIntRect(nsIntPoint(0, 0), mSize); - //printf_stderr("v Forcing full paint\n"); - aRegion = nsIntRegion(mUpdateRect); - } else { - mUpdateRect = aRegion.GetBounds(); - if (!mBackingSurface) { - // We can only draw a rectangle, not subregions due to - // the way that our texture upload functions work. If - // needed, we /could/ do multiple texture uploads if we have - // non-overlapping rects, but that's a tradeoff. - aRegion = nsIntRegion(mUpdateRect); - } - } + GetUpdateRegion(aRegion); + mUpdateRect = aRegion.GetBounds(); //printf_stderr("BeginUpdate with updateRect [%d %d %d %d]\n", mUpdateRect.x, mUpdateRect.y, mUpdateRect.width, mUpdateRect.height); if (!nsIntRect(nsIntPoint(0, 0), mSize).Contains(mUpdateRect)) { From ee19435552cdc42a89af819b0925d8797a7d170b Mon Sep 17 00:00:00 2001 From: Chris Lord Date: Fri, 19 Aug 2011 09:36:08 +0100 Subject: [PATCH 02/71] Bug 611315 - Fix drawing of tiled GL Thebes layers with rotation. r=mattwoodrow Drawing of rotated buffers relies on texture-wrapping, but in the case of tiled textures, this would cause each individual tile to wrap instead of wrapping the compound texture. Add a special case for tiled textures that manually does the wrapping. --- gfx/layers/opengl/ThebesLayerOGL.cpp | 100 +++++++++++++++++++++------ gfx/thebes/GLContext.cpp | 5 ++ gfx/thebes/GLContext.h | 6 ++ 3 files changed, 89 insertions(+), 22 deletions(-) diff --git a/gfx/layers/opengl/ThebesLayerOGL.cpp b/gfx/layers/opengl/ThebesLayerOGL.cpp index 91fd36c40ee7..83fe201c04b8 100644 --- a/gfx/layers/opengl/ThebesLayerOGL.cpp +++ b/gfx/layers/opengl/ThebesLayerOGL.cpp @@ -191,40 +191,96 @@ ThebesLayerBufferOGL::RenderTo(const nsIntPoint& aOffset, renderRegion = &visibleRegion; } - mTexImage->BeginTileIteration(); - if (mTexImageOnWhite) { - mTexImageOnWhite->BeginTileIteration(); - NS_ASSERTION(mTexImageOnWhite->GetTileRect() == mTexImage->GetTileRect(), "component alpha textures should be the same size."); - } nsIntRegion region(*renderRegion); nsIntPoint origin = GetOriginOffset(); region.MoveBy(-origin); // translate into TexImage space, buffer origin might not be at texture (0,0) + // Figure out the intersecting draw region + nsIntSize texSize = mTexImage->GetSize(); + nsIntRect textureRect = nsIntRect(0, 0, texSize.width, texSize.height); + textureRect.MoveBy(region.GetBounds().TopLeft()); + nsIntRegion subregion; + subregion.And(region, textureRect); + if (subregion.IsEmpty()) // Region is empty, nothing to draw + return; + + nsIntRegion screenRects; + nsIntRegion regionRects; + + // Collect texture/screen coordinates for drawing + nsIntRegionRectIterator iter(subregion); + while (const nsIntRect* iterRect = iter.Next()) { + nsIntRect regionRect = *iterRect; + nsIntRect screenRect = regionRect; + screenRect.MoveBy(origin); + + screenRects.Or(screenRects, screenRect); + regionRects.Or(regionRects, regionRect); + } + + mTexImage->BeginTileIteration(); + if (mTexImageOnWhite) { + NS_ASSERTION(mTexImage->GetTileCount() == mTexImageOnWhite->GetTileCount(), + "Tile count mismatch on component alpha texture"); + mTexImageOnWhite->BeginTileIteration(); + } + + bool usingTiles = (mTexImage->GetTileCount() > 1); do { - nsIntRect textureRect = mTexImage->GetTileRect(); - textureRect.MoveBy(region.GetBounds().x, region.GetBounds().y); - nsIntRegion subregion(region); - subregion.And(region, textureRect); // region this texture is visible in - if (subregion.IsEmpty()) { - continue; + if (mTexImageOnWhite) { + NS_ASSERTION(mTexImageOnWhite->GetTileRect() == mTexImage->GetTileRect(), "component alpha textures should be the same size."); } + + nsIntRect tileRect = mTexImage->GetTileRect(); + // Bind textures. TextureImage::ScopedBindTexture texBind(mTexImage, LOCAL_GL_TEXTURE0); TextureImage::ScopedBindTexture texOnWhiteBind(mTexImageOnWhite, LOCAL_GL_TEXTURE1); - nsIntRegionRectIterator iter(subregion); - while (const nsIntRect *iterRect = iter.Next()) { - nsIntRect regionRect = *iterRect; // one rectangle of this texture's region - // translate into the correct place for this texture sub-region - nsIntRect screenRect = regionRect; - screenRect.MoveBy(origin); - program->SetLayerQuadRect(screenRect); + // Draw texture. If we're using tiles, we do repeating manually, as texture + // repeat would cause each individual tile to repeat instead of the + // compound texture as a whole. This involves drawing at most 4 sections, + // 2 for each axis that has texture repeat. + for (int y = 0; y < (usingTiles ? 2 : 1); y++) { + for (int x = 0; x < (usingTiles ? 2 : 1); x++) { + nsIntRect currentTileRect(tileRect); + currentTileRect.MoveBy(x * texSize.width, y * texSize.height); - regionRect.MoveBy(-mTexImage->GetTileRect().TopLeft()); // get region of tile - aManager->BindAndDrawQuadWithTextureRect(program, regionRect, - textureRect.Size(), - mTexImage->GetWrapMode()); + nsIntRegionRectIterator screenIter(screenRects); + nsIntRegionRectIterator regionIter(regionRects); + + const nsIntRect* screenRect; + const nsIntRect* regionRect; + while ((screenRect = screenIter.Next()) && + (regionRect = regionIter.Next())) { + nsIntRect tileScreenRect(*screenRect); + nsIntRect tileRegionRect(*regionRect); + + // When we're using tiles, find the intersection between the tile + // rect and this region rect. Tiling is then handled by the + // outer for-loops and modifying the tile rect. + if (usingTiles) { + tileScreenRect.MoveBy(-origin); + tileScreenRect = tileScreenRect.Intersect(currentTileRect); + tileScreenRect.MoveBy(origin); + + if (tileScreenRect.IsEmpty()) + continue; + + tileRegionRect = regionRect->Intersect(currentTileRect); + tileRegionRect.MoveBy(-currentTileRect.TopLeft()); + } + + program->SetLayerQuadRect(tileScreenRect); + aManager->BindAndDrawQuadWithTextureRect(program, tileRegionRect, + tileRect.Size(), + mTexImage->GetWrapMode()); + } + } } + + if (mTexImageOnWhite) + mTexImageOnWhite->NextTile(); } while (mTexImage->NextTile()); } diff --git a/gfx/thebes/GLContext.cpp b/gfx/thebes/GLContext.cpp index 4611ad5ef8ce..443fa8a961fa 100644 --- a/gfx/thebes/GLContext.cpp +++ b/gfx/thebes/GLContext.cpp @@ -954,6 +954,11 @@ void TiledTextureImage::Resize(const nsIntSize& aSize) mTextureState = Allocated; } +PRUint32 TiledTextureImage::GetTileCount() +{ + return mImages.Length(); +} + PRBool GLContext::ResizeOffscreenFBO(const gfxIntSize& aSize) { diff --git a/gfx/thebes/GLContext.h b/gfx/thebes/GLContext.h index 4428690e4c09..72e4a4957d43 100644 --- a/gfx/thebes/GLContext.h +++ b/gfx/thebes/GLContext.h @@ -227,6 +227,11 @@ public: }; virtual GLuint GetTextureID() = 0; + + virtual PRUint32 GetTileCount() { + return 1; + }; + /** * Set this TextureImage's size, and ensure a texture has been * allocated. Must not be called between BeginUpdate and EndUpdate. @@ -405,6 +410,7 @@ public: virtual void GetUpdateRegion(nsIntRegion& aForRegion); virtual void EndUpdate(); virtual void Resize(const nsIntSize& aSize); + virtual PRUint32 GetTileCount(); virtual void BeginTileIteration(); virtual PRBool NextTile(); virtual nsIntRect GetTileRect(); From db10ec99c6398d1e477548f12dbc9f019339a287 Mon Sep 17 00:00:00 2001 From: Chris Lord Date: Fri, 19 Aug 2011 09:36:18 +0100 Subject: [PATCH 03/71] Bug 611315 - Fix handling of rotated ShadowBufferOGL. r=mattwoodrow Although we currently have buffer rotation disabled for shadow buffers when using the GL layer manager, if you re-enable it, it will be broken. This is because we don't take into account the rotation when handling uploads. This fixes that handling by offsetting the updated region by the rotation and adds an assertion if the updated region crosses a rotation boundary (which should never happen). --- gfx/layers/opengl/ThebesLayerOGL.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/gfx/layers/opengl/ThebesLayerOGL.cpp b/gfx/layers/opengl/ThebesLayerOGL.cpp index 83fe201c04b8..e8b2687cd1ed 100644 --- a/gfx/layers/opengl/ThebesLayerOGL.cpp +++ b/gfx/layers/opengl/ThebesLayerOGL.cpp @@ -847,6 +847,18 @@ ShadowBufferOGL::Upload(gfxASurface* aUpdate, const nsIntRegion& aUpdated, nsIntPoint visTopLeft = mLayer->GetVisibleRegion().GetBounds().TopLeft(); destRegion.MoveBy(-visTopLeft); + // Correct for rotation + destRegion.MoveBy(aRotation); + nsIntRect destBounds = destRegion.GetBounds(); + destRegion.MoveBy((destBounds.x >= size.width) ? -size.width : 0, + (destBounds.y >= size.height) ? -size.height : 0); + + // There's code to make sure that updated regions don't cross rotation + // boundaries, so assert here that this is the case + NS_ASSERTION(((destBounds.x % size.width) + destBounds.width <= size.width) && + ((destBounds.y % size.height) + destBounds.height <= size.height), + "Updated region lies across rotation boundaries!"); + // NB: this gfxContext must not escape EndUpdate() below mTexImage->DirectUpdate(aUpdate, destRegion); From 25cc2c28f479cb49b1df4e9e96131be1d090bf27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A3o=20Gottwald?= Date: Fri, 19 Aug 2011 11:17:39 +0200 Subject: [PATCH 04/71] Bug 673528 - Only add www and a domain suffix when the typed domain contains no dot, colon or space. r=gavin, ui-r=faaborg --- browser/base/content/test/Makefile.in | 1 + .../base/content/test/browser_canonizeURL.js | 54 +++++++++++++++++++ browser/base/content/urlbarBindings.xml | 21 +++----- 3 files changed, 61 insertions(+), 15 deletions(-) create mode 100644 browser/base/content/test/browser_canonizeURL.js diff --git a/browser/base/content/test/Makefile.in b/browser/base/content/test/Makefile.in index 4cc801b13d3f..e643dab3c974 100644 --- a/browser/base/content/test/Makefile.in +++ b/browser/base/content/test/Makefile.in @@ -177,6 +177,7 @@ _BROWSER_FILES = \ browser_bug647886.js \ browser_bug655584.js \ browser_bug664672.js \ + browser_canonizeURL.js \ browser_findbarClose.js \ browser_keywordBookmarklets.js \ browser_contextSearchTabPosition.js \ diff --git a/browser/base/content/test/browser_canonizeURL.js b/browser/base/content/test/browser_canonizeURL.js new file mode 100644 index 000000000000..b544416f96fa --- /dev/null +++ b/browser/base/content/test/browser_canonizeURL.js @@ -0,0 +1,54 @@ +function test() { + waitForExplicitFinish(); + testNext(); +} + +var pairs = [ + ["example", "http://www.example.net/"], + ["ex-ample", "http://www.ex-ample.net/"], + [" example ", "http://www.example.net/"], + [" example/foo ", "http://www.example.net/foo"], + [" example/foo bar ", "http://www.example.net/foo%20bar"], + ["example.net", "http://example.net/"], + ["http://example", "http://example/"], + ["example:8080", "http://example:8080/"], + ["ex-ample.foo", "http://ex-ample.foo/"], + ["example.foo/bar ", "http://example.foo/bar"], + ["1.1.1.1", "http://1.1.1.1/"], + ["ftp://example", "ftp://example/"], + ["ftp.example.bar", "ftp://ftp.example.bar/"], + ["ex ample", Services.search.originalDefaultEngine.getSubmission("ex ample").uri.spec], +]; + +function testNext() { + if (!pairs.length) { + finish(); + return; + } + + let [inputValue, expectedURL] = pairs.shift(); + + gBrowser.addProgressListener({ + onStateChange: function onStateChange(aWebProgress, aRequest, aStateFlags, aStatus) { + if (aStateFlags & Ci.nsIWebProgressListener.STATE_START && + aStateFlags & Ci.nsIWebProgressListener.STATE_IS_NETWORK) { + is(aRequest.originalURI.spec, expectedURL, + "entering '" + inputValue + "' loads expected URL"); + + gBrowser.removeProgressListener(this); + gBrowser.stop(); + + executeSoon(testNext); + } + } + }); + + gURLBar.addEventListener("focus", function onFocus() { + gURLBar.removeEventListener("focus", onFocus); + EventUtils.synthesizeKey("VK_RETURN", { shiftKey: true }); + }); + + gBrowser.selectedBrowser.focus(); + gURLBar.inputField.value = inputValue; + gURLBar.focus(); +} diff --git a/browser/base/content/urlbarBindings.xml b/browser/base/content/urlbarBindings.xml index 2278e5f7b5c6..641e750a43b5 100644 --- a/browser/base/content/urlbarBindings.xml +++ b/browser/base/content/urlbarBindings.xml @@ -367,7 +367,7 @@ // Only add the suffix when the URL bar value isn't already "URL-like", // and only if we get a keyboard event, to match user expectations. - if (!/^\s*(www|https?)\b|\/\s*$/i.test(url) && + if (/^\s*[^.:\/\s]+(?:\/.*|\s*)$/i.test(url) && (aTriggeringEvent instanceof KeyEvent)) { #ifdef XP_MACOSX let accel = aTriggeringEvent.metaKey; @@ -402,24 +402,15 @@ // Tack www. and suffix on. If user has appended directories, insert // suffix before them (bug 279035). Be careful not to get two slashes. - // Also, don't add the suffix if it's in the original url (bug 233853). let firstSlash = url.indexOf("/"); - let existingSuffix = url.indexOf(suffix.substring(0, suffix.length - 1)); - - // * Logic for slash and existing suffix (example) - // No slash, no suffix: Add suffix (mozilla) - // No slash, yes suffix: Add slash (mozilla.com) - // Yes slash, no suffix: Insert suffix (mozilla/stuff) - // Yes slash, suffix before slash: Do nothing (mozilla.com/stuff) - // Yes slash, suffix after slash: Insert suffix (mozilla/?stuff=.com) if (firstSlash >= 0) { - if (existingSuffix == -1 || existingSuffix > firstSlash) - url = url.substring(0, firstSlash) + suffix + - url.substring(firstSlash + 1); - } else - url = url + (existingSuffix == -1 ? suffix : "/"); + url = url.substring(0, firstSlash) + suffix + + url.substring(firstSlash + 1); + } else { + url = url + suffix; + } url = "http://www." + url; } From 288d934728adb7fd1f2c32f079f08af36e68b5dc Mon Sep 17 00:00:00 2001 From: Oleg Romashin Date: Fri, 19 Aug 2011 12:47:03 +0200 Subject: [PATCH 05/71] Bug 679987 - [CGroups] fennec and plugin-container need to be both boosted on foreground. r=dougt --- mobile/installer/Makefile.in | 4 +++- mobile/installer/debian/fennec.policy.in | 4 ++++ 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 mobile/installer/debian/fennec.policy.in diff --git a/mobile/installer/Makefile.in b/mobile/installer/Makefile.in index 52478d7da3fb..6a01d5bfb070 100644 --- a/mobile/installer/Makefile.in +++ b/mobile/installer/Makefile.in @@ -189,6 +189,7 @@ PP_DEB_FILES += debian/backup \ debian/fennec.conf \ debian/fennec-cud.sh \ debian/fennec-rfs.sh \ + debian/fennec.policy \ $(NULL) endif @@ -224,7 +225,8 @@ ifeq ($(MOZ_PLATFORM_MAEMO),6) cp debian/$(MOZ_APP_NAME).conf $(DEBDESTDIR)/usr/share/backup-framework/applications/$(MOZ_APP_NAME).conf cp debian/$(MOZ_APP_NAME)-cud.sh $(DEBDESTDIR)/etc/osso-cud-scripts/$(MOZ_APP_NAME)-cud.sh cp debian/$(MOZ_APP_NAME)-rfs.sh $(DEBDESTDIR)/etc/osso-rfs-scripts/$(MOZ_APP_NAME)-rfs.sh - + $(NSINSTALL) -D $(DEBDESTDIR)/usr/share/policy/etc/syspart.conf.d + cp debian/$(MOZ_APP_NAME).policy $(DEBDESTDIR)/usr/share/policy/etc/syspart.conf.d/$(MOZ_APP_NAME) else $(NSINSTALL) debian/$(MOZ_APP_NAME).desktop $(DEBDESTDIR)/usr/share/applications/hildon/ $(NSINSTALL) -D $(DEBDESTDIR)/usr/share/dbus-1/services/ diff --git a/mobile/installer/debian/fennec.policy.in b/mobile/installer/debian/fennec.policy.in new file mode 100644 index 000000000000..98912d518812 --- /dev/null +++ b/mobile/installer/debian/fennec.policy.in @@ -0,0 +1,4 @@ +#filter substitution +[classify browser] +@installdir@/@MOZ_APP_NAME@ +@installdir@/plugin-container From d45852fa1e6d7c8c43eda0ee6df4d0b25c195c56 Mon Sep 17 00:00:00 2001 From: Hiroyuki Ikezoe Date: Fri, 19 Aug 2011 12:52:07 +0200 Subject: [PATCH 06/71] Bug 678452 - Fix misuse of NS_ENSURE_ARG_POINTER. r=roc --- gfx/src/nsThebesFontEnumerator.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/gfx/src/nsThebesFontEnumerator.cpp b/gfx/src/nsThebesFontEnumerator.cpp index d1e5f817d97f..46024e1fdbce 100644 --- a/gfx/src/nsThebesFontEnumerator.cpp +++ b/gfx/src/nsThebesFontEnumerator.cpp @@ -107,8 +107,7 @@ NS_IMETHODIMP nsThebesFontEnumerator::HaveFontFor(const char *aLangGroup, PRBool *aResult) { - NS_ENSURE_ARG_POINTER(*aResult); - NS_ENSURE_ARG_POINTER(*aLangGroup); + NS_ENSURE_ARG_POINTER(aResult); *aResult = PR_TRUE; return NS_OK; From 744c72756ed0290bc83feb1f72199cc326ab9ddb Mon Sep 17 00:00:00 2001 From: Matheus Kerschbaum Date: Fri, 19 Aug 2011 12:53:03 +0200 Subject: [PATCH 07/71] Bug 679615 - Remove config/gtscc.c r=ted --- config/gtscc.c | 2809 ------------------------- toolkit/mozapps/installer/packager.mk | 1 - 2 files changed, 2810 deletions(-) delete mode 100644 config/gtscc.c diff --git a/config/gtscc.c b/config/gtscc.c deleted file mode 100644 index 638d7d6ee7f5..000000000000 --- a/config/gtscc.c +++ /dev/null @@ -1,2809 +0,0 @@ -/* -*- Mode: C; tab-width: 4; 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 ***** */ -/* */ -/* - *-------------------------------------------------------------------------- - * - * - * - *-------------------------------------------------------------------------- - * - * gtscc - Global To Static C/C++ compiler driver. - * - * Syntax: - * - * gtscc [options] -c file.cpp ... - * gtscc [options] file.o ... libxx.a ... - * - * gtscc is a compiler and linker driver/wrapper for Irix only. - * gtscc takes all compiler options and passes them onto the Irix - * cc/CC compiler/linker. - * Typically, gtscc is used in two phases. Phase one is during compilation. - * gtscc, the compiler, converts all inline globals to statics, and records - * the existence of other globals and how to compile the file in the gtscc - * database file. - * During linking, globals dependencies are analyzed, and a list of - * "convertable" globals is determined. Globals that are not referenced - * globally, but are referenced locally are considered convertable. - * The linker then recompiles the files that those symbols are in, and - * converts them to statics. It also calls the archiver to install - * the converted objects into libraries. - * Finally the linker is called. - * - * Created: David Williams, djw@netscape.com, 13-Feb-1997 - * - *-------------------------------------------------------------------------- - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(LINUX) && defined(__GLIBC__) -#include -#else -#include -#endif - -#include -#include -#include - -#define DEFAULT_MAX_GLOBALS 15500 - -#define ELFSYM_IS_DEFINED(x) ((x).st_shndx != SHN_UNDEF) -#define ELFSYM_IS_UNDEFINED(x) ((x).st_shndx == SHN_UNDEF) - -#ifdef IRIX -#define CC_COMMAND "cc" -#define CCC_COMMAND "CC" -#define AS_COMMAND "cc" -#define LD_COMMAND "CC" -#define AR_COMMAND "ar" -#define AR_OPTIONS "cr" -#else -#define HANDLES_DASHSO -#define CC_COMMAND "gcc" -#define CCC_COMMAND "g++" -#define AS_COMMAND "gcc" -#define LD_COMMAND "g++" -#define AR_COMMAND "ar" -#define AR_OPTIONS "cr" -#endif - -#define EH_NEW(type) (type*)malloc(sizeof(type)) - -#define TRUE 1 -#define FALSE 0 - -#define EH_TAG_FILE 'F' -#define EH_TAG_GLOBAL 'G' -#define EH_TAG_ZAPPED 'Z' -#define EH_TAG_INLINE 'I' -#define EH_TAG_UNDEFINED 'U' - -#define VERBOSITY_USER(x) ((x) > 0) -#define VERBOSITY_DEBUG(x) ((x) > 1) -#define VERBOSITY_MAJOR(x) ((x) > 2) - -static char eh_unnamed_object[] = ""; - -typedef struct { - char* name; /* archive */ -} EhArchive; - -typedef struct { - char* name; /* name of C/C++ file, relative to rootdir */ - char* directory;/* must compile in this directory */ - char** cc_args; /* cc -I ..... */ - char* as_savefile; - time_t compile_time; - char* target_object; -} EhSource; - -typedef struct EhObject { - struct EhObject* _recompile; /* used for recompilation link list */ - unsigned _needs_unzap; - char* name; /* name of .o */ - EhArchive* archive; /* it is stored in */ - EhSource* source; - char* pathname; - unsigned nusers; -} EhObject; - -typedef enum { - EH_SYM_UNDEFINED, - EH_SYM_DEFINED, - EH_SYM_ZAPPED, - EH_SYM_INLINE /* are treated special - they belong to no file */ -} EhSymState; - -typedef struct EhSym { - struct EhSym* _next; /* used for link list */ - char* name; /* name of symbol */ - EhObject* object; /* if symbol is undefined == NULL */ - unsigned ngusers; /* number of global users */ - unsigned nlusers; /* number of local file users */ - -#if 0 - unsigned section; /* section in elf file */ - unsigned index; /* index into symbol table */ - unsigned char info; - unsigned dirty; -#endif - EhSymState state; -} EhSym; - -#define EHSYM_ISDEFINED(x) ((x)->object!=NULL && (x)->state==EH_SYM_DEFINED) -#define EHSYM_ISZAPPED(x) ((x)->object!=NULL && (x)->state==EH_SYM_ZAPPED) -#define EHSYM_ISUNDEFINED(x) ((x)->object == NULL) -#define EHSYM_ISUSED(x) ((x)->nusers != 0) -#define EHSYM_ISINLINE(x) ((x)->state == EH_SYM_INLINE) - -#define EH_OBJECT_CANBUILD(x) \ -((x)->source != NULL && (x)->name != eh_unnamed_object) - -#define USE_HASHING - -typedef struct { -#ifdef USE_HASHING - EhSym** heads; - unsigned size; -#else - EhSym* head; -#endif - unsigned nentries; -} EhSymTable; - -static char* -make_relative_pathname(char* buf, char* filename, char* rootdir) -{ - char buf1[MAXPATHLEN]; - char buf2[MAXPATHLEN]; - char* p; - char* q; - - if (rootdir == NULL) { - strcpy(buf, filename); - return filename; - } - - if (filename[0] != '/') { - if (getcwd(buf2, sizeof(buf2)) == NULL) { - fprintf(stderr, "cannot get pwd\n"); - return NULL; - } - - strcat(buf2, "/"); - strcat(buf2, filename); - - filename = buf2; - } - - if (realpath(filename, buf1) == NULL) { - fprintf(stderr, "realpath(%s,..) failed\n", filename); - return NULL; - } - - if (realpath(rootdir, buf2) == NULL) { - fprintf(stderr, "realpath(%s,..) failed\n", rootdir); - return NULL; - } - - strcat(buf2, "/"); - - for (p = buf1, q = buf2; *p == *q; p++, q++) - ; - - strcpy(buf, p); - - return buf; -} - -static EhArchive* -EhArchiveNew(char* name, char* rootdir) -{ - EhArchive* archive = EH_NEW(EhArchive); - char pathbuf[MAXPATHLEN]; - - make_relative_pathname(pathbuf, name, rootdir); - - archive->name = strdup(pathbuf); - - return archive; -} - -#if 0 -/* - * This is evil, we should never free anything, because it messes up - * interning. - */ -static void -EhSourceDelete(EhSource* source) -{ - unsigned n; - if (source->name != NULL) - free(source->name); - if (source->directory != NULL) - free(source->directory); - if (source->cc_args != NULL) { - for (n = 0; source->cc_args[n] != NULL; n++) - free(source->cc_args[n]); - free(source->cc_args); - } - if (source->as_savefile != NULL) - free(source->as_savefile); -} -#endif - -static EhSource* -EhSourceNew(char* name, char** cc_args, char* directory) -{ - EhSource* source = EH_NEW(EhSource); - unsigned n; - unsigned m; - - source->name = strdup(name); - source->directory = (directory != NULL)? strdup(directory): NULL; - source->as_savefile = NULL; - source->compile_time = 0; - source->target_object = NULL; - source->cc_args = NULL; - - if (cc_args != NULL) { - - for (n = 0; cc_args[n] != NULL; n++) - ; - - source->cc_args = (char**)malloc(sizeof(char*) * (n+1)); - - for (m = 0, n = 0; cc_args[n] != NULL;) { - if (strcmp(cc_args[n], "-o") == 0 && cc_args[n+1] != NULL) { - source->target_object = strdup(cc_args[n+1]); - n += 2; - } else { - source->cc_args[m++] = strdup(cc_args[n++]); - } - } - - source->cc_args[m] = NULL; - } - - return source; -} - -static EhObject* -EhObjectNewArchiveObject(EhArchive* archive, char* name) -{ - EhObject* object = EH_NEW(EhObject); - - if (name == eh_unnamed_object) - object->name = name; - else - object->name = strdup(name); - object->archive = archive; - object->source = NULL; - object->_recompile = NULL; - object->_needs_unzap = 0; - object->pathname = NULL; - object->nusers = 0; - - return object; -} - -static EhObject* -EhObjectNew(char* name, char* rootdir) -{ - EhObject* object = EhObjectNewArchiveObject(NULL, name); - char pathname[MAXPATHLEN]; - - make_relative_pathname(pathname, name, rootdir); - object->pathname = strdup(pathname); - - return object; -} - -static EhObject* -EhObjectNewFromSource(EhSource* source) -{ - EhObject* object = EhObjectNewArchiveObject(NULL, eh_unnamed_object); - - object->source = source; - - return object; -} - -static char* -EhObjectGetFilename(EhObject* object, char* buf) -{ - if (object->archive) { - strcpy(buf, object->archive->name); - strcat(buf, ":"); - strcat(buf, object->name); - return buf; - } else { - return object->name; - } -} - -static EhSym* -EhSymNewDefined(char* name, EhObject* object) -{ - EhSym* sym = EH_NEW(EhSym); - - sym->name = strdup(name); - sym->object = object; - sym->state = EH_SYM_DEFINED; - sym->ngusers = 0; - sym->nlusers = 0; - - return sym; -} - -static EhSym* -EhSymNewInline(char* name) -{ - EhSym* sym = EhSymNewDefined(name, NULL); - sym->state = EH_SYM_INLINE; - - return sym; -} - -static EhSym* -EhSymNewUndefined(char* name) -{ - EhSym* sym = EhSymNewDefined(name, NULL); - sym->state = EH_SYM_UNDEFINED; - - return sym; -} - -static EhSym* -EhSymNewZapped(char* name, EhObject* object) -{ - EhSym* sym = EhSymNewDefined(name, object); - sym->state = EH_SYM_ZAPPED; - - return sym; -} - -static EhSym* -EhSymNewRandomZap(char* name) -{ - EhSym* sym = EhSymNewZapped(name, NULL); - - return sym; -} - -EhSymTable* -EhSymTableNew(unsigned p_size) -{ - EhSymTable* table = EH_NEW(EhSymTable); - -#ifdef USE_HASHING - unsigned size; - for (size = 0x1; size < (16*1024); size <<= 1) { - if (size >= p_size) - break; - } - table->size = size; - table->heads = (EhSym**)calloc(size, sizeof(EhSym*)); -#else - table->head = NULL; -#endif - table->nentries = 0; - - return table; -} - -EhSym* -EhSymTableInsert(EhSymTable* table, EhSym* sym) -{ -#ifdef USE_HASHING - unsigned long hash = elf_hash(sym->name); - unsigned long mask = table->size - 1; - unsigned index = (hash & mask); - - sym->_next = table->heads[index]; - table->heads[index] = sym; -#else - sym->_next = table->head; - table->head = sym; -#endif - table->nentries++; - - return sym; -} - -EhSym* -EhSymTableFind(EhSymTable* table, char* name) -{ - EhSym* sym; - EhSym* head; - -#ifdef USE_HASHING - unsigned long hash = elf_hash(name); - unsigned long mask = table->size - 1; - unsigned index = (hash & mask); - head = table->heads[index]; -#else - head = table->head; -#endif - - for (sym = head; sym != NULL; sym = sym->_next) { - if (strcmp(name, sym->name) == 0) - break; - } - - return sym; -} - -typedef int (*eh_dump_mappee_t)(EhSym* sym, void* arg); - -static int -EhSymTableMap(EhSymTable* table, eh_dump_mappee_t func, void* arg) -{ - EhSym* sym; - EhSym* head; - -#ifdef USE_HASHING - unsigned n; - for (n = 0; n < table->size; n++) { - head = table->heads[n]; -#else - head = table->head; { -#endif - for (sym = head; sym != NULL; sym = sym->_next) { - if ((func)(sym, arg) == -1) - return -1; - } - } - - return 0; -} - -typedef struct { - EhObject* o_old; - EhObject* o_new; -} fixup_info; - -static int -fixup_mappee(EhSym* sym, void* arg) -{ - fixup_info* info = (fixup_info*)arg; - - if (sym->object == info->o_old) - sym->object = info->o_new; - - return 0; -} - -static EhObject* -EhSymTableObjectFixup(EhSymTable* table, EhObject* o_old, EhObject* o_new) -{ - fixup_info info; - - /* - * Now visit every sym that pointed to tmp, and point it - * at object. - */ - info.o_old = o_old; - info.o_new = o_new; - EhSymTableMap(table, fixup_mappee, &info); - - return o_new; -} - - - -static char* -safe_fgets(char* buf, unsigned size, FILE* fp) -{ - unsigned nread = 0; - - if (buf == NULL) - buf = (char*)malloc(size); - - for (;;) { - - if (fgets(&buf[nread], size - nread, fp) == NULL) { - free(buf); - return NULL; - } - - if (strchr(buf, '\n') != NULL) - return buf; - - /* - * fgets returns n-1 characters and \0 - */ - nread += (size - nread) - 1; - size += 1024; - buf = (char*)realloc(buf, size); - } -} - -static int -EhSymTableSetSymbolState(EhSymTable* table, char* name, EhSymState new_state) -{ - EhSym* sym = EhSymTableFind(table, name); - - if (sym == NULL) { - sym = EhSymNewDefined(name, NULL); - - EhSymTableInsert(table, sym); - } - - /* new_state must be EH_SYM_DEFINED || EH_SYM_ZAPPED */ - if (sym->state == EH_SYM_DEFINED || sym->state == EH_SYM_ZAPPED) { - sym->state = new_state; - } else if (sym->state == EH_SYM_INLINE) { - char* state_name; - if (new_state == EH_SYM_DEFINED) - state_name = "global"; - else - state_name = "static"; - fprintf(stderr, - "WARNING: Symbol %s is an inline.\n" - " Forcing the symbol %s will be ignored.\n", - name, - state_name); - } else { /* EH_SYM_UNDEFINED */ - /* - * This call is being made after objects have started being - * read. This is too late. I'm not sure I care though. - */ - return -1; - } - - return 0; -} - -static int -EhSymTableFpLoad(EhSymTable* table, FILE* fp) -{ - char* buf = NULL; /* I hope this is big enough */ - char* p; - char* name; - char* state; - EhSym* sym; - EhSource* source = NULL; - EhObject* object = NULL; - char* cc_args[512]; - unsigned n; - unsigned line_n = 0; - char* ctime = NULL; - char* directory; - char* savefile; - - while ((buf = safe_fgets(buf, 1024, fp)) != NULL) { - - if ((p = strchr(buf, '\n')) == NULL) { - fprintf(stderr, "line to long: %d\n", line_n); - return -1; - } - *p = '\0'; - - line_n++; - - if (buf[0] == '!') /* comment */ - continue; - - for (p = buf; isspace(*p); p++) - ; - - name = p; - for (; !isspace(*p); p++) - ; - *p++ = '\0'; - - if (name[0] == '\0') - continue; - - for (; isspace(*p); p++) - ; - - state = p; - for (; !isspace(*p) && *p != '\0'; p++) - ; - *p++ = '\0'; - - if (state[0] == EH_TAG_GLOBAL - || - state[0] == EH_TAG_ZAPPED - || - state[0] == EH_TAG_INLINE) { - sym = EhSymTableFind(table, name); - if (sym == NULL) { /* install a new one */ - - if (source == NULL && state[0] != EH_TAG_INLINE) { - fprintf(stderr, - "[%d] found new style symbol (%s) but no source\n", - line_n, name); - } - - if (state[0] == EH_TAG_GLOBAL) - sym = EhSymNewDefined(name, object); - else if (state[0] == EH_TAG_INLINE) - sym = EhSymNewInline(name); - else - sym = EhSymNewZapped(name, object); - - EhSymTableInsert(table, sym); - } else { - if (state[0] == EH_TAG_GLOBAL) { - if (sym->state != EH_SYM_DEFINED) { - fprintf(stderr, - "out of sync defined symbol: %s, fixing\n", - sym->name); - sym->state = EH_SYM_DEFINED; - } - } else if (state[0] == EH_TAG_INLINE) { - if (sym->state != EH_SYM_INLINE) { - fprintf(stderr, - "out of sync inlined symbol: %s, fixing\n", - sym->name); - sym->state = EH_SYM_INLINE; - } - } else { - if (sym->state != EH_SYM_ZAPPED) { - fprintf(stderr, - "out of sync zapped symbol: %s, fixing\n", - sym->name); - sym->state = EH_SYM_ZAPPED; - } - } - -#if 0 - /* these are probably "special" symbols like .div */ - if (sym->object != object) { - fprintf(stderr, - "out of sync object for symbol: %s, ignoring\n", - sym->name); - } -#endif - } - - continue; /* no more fields we care about */ - } else if (state[0] == EH_TAG_FILE) { - - directory = p; - for (; !isspace(*p) && *p != '\0'; p++) - ; - *p++ = '\0'; - - savefile = p; - for (; !isspace(*p) && *p != '\0'; p++) - ; - *p++ = '\0'; - - ctime = p; - for (; !isspace(*p) && *p != '\0'; p++) - ; - *p++ = '\0'; - - for (n = 0; *p != '\0';) { - - for (; isspace(*p); p++) - ; - - cc_args[n++] = p++; - - for (; !isspace(*p) && *p != '\0'; p++) - ; - - if (*p == '\0') - break; - - *p++ = '\0'; - } - cc_args[n] = NULL; - - if (strcmp(directory, ".") == 0) - directory = NULL; - source = EhSourceNew(name, cc_args, directory); - if (ctime != NULL) - source->compile_time = (time_t)atoi(ctime); - object = EhObjectNewFromSource(source); - - } else { /* old style symbol list */ - sym = EhSymTableFind(table, name); - if (sym != NULL) { - if (sym->state != EH_SYM_ZAPPED) { - fprintf(stderr, - "out of sync random zapped symbol: %s, fixing\n", - sym->name); - sym->state = EH_SYM_ZAPPED; - } - } else { - sym = EhSymNewRandomZap(name); - } - } - } - - return line_n; -} - -typedef struct { - EhSym** vector; - unsigned index; -} flush_info; - -static int -flush_mappee(EhSym* sym, void* arg) -{ - flush_info* info = (flush_info*)arg; - - if (sym->state == EH_SYM_INLINE - || - (sym->object != NULL && sym->state == EH_SYM_DEFINED) - || - (sym->object != NULL && sym->state == EH_SYM_ZAPPED)) { - if (info->vector != NULL) - info->vector[info->index] = sym; - info->index++; - } - - return 0; -} - -static int -flush_compare(const void* ap, const void* bp) -{ - EhSym** ax = (EhSym**)ap; - EhSym** bx = (EhSym**)bp; - EhSym* a = *ax; - EhSym* b = *bx; - EhObject* oa = a->object; - EhObject* ob = b->object; - int foo; - - if (oa == NULL && ob != NULL) - return -1; - if (oa != NULL && ob == NULL) - return 1; - if (oa == NULL && ob == NULL) { - foo = strcmp(a->name, b->name); - if (foo < 0) - return -1; - else if (foo > 0) - return 1; - return 0; - } - - if (oa->source == NULL && ob->source != NULL) - return -1; - if (oa->source != NULL && ob->source == NULL) - return 1; - if (oa->source == ob->source) - return 0; - if (oa->source < ob->source) - return -1; - if (oa->source > ob->source) - return 1; - foo = strcmp(a->name, b->name); - if (foo < 0) - return -1; - else if (foo > 0) - return 1; - return 0; -} - -static void -EhSourceFpWrite(EhSource* source, FILE* fp) -{ - unsigned n = 0; - - fputs(source->name, fp); - fputc(' ', fp); - fputc(EH_TAG_FILE, fp); - - fputc(' ', fp); - if (source->directory != NULL) - fprintf(fp, "%s", source->directory); - else - fputc('.', fp); - - fputc(' ', fp); - if (source->as_savefile != NULL) - fprintf(fp, "%s", source->as_savefile); - else - fputc('.', fp); - - fputc(' ', fp); - fprintf(fp, "%d", source->compile_time); - - if (source->target_object != NULL) { - fputs(" -o ", fp); - fputs(source->target_object, fp); - } - - if (source->cc_args != NULL) { - for (n = 0; source->cc_args[n] != NULL; n++) { - fputc(' ', fp); - fputs(source->cc_args[n], fp); - } - } - - if (n < 1) - fprintf(stderr, "WARNING: %s has no args\n", source->name); - - fputc('\n', fp); -} - -static int -EhSymTableFpDump(EhSymTable* table, FILE* fp) -{ - flush_info info; - unsigned n; - EhObject* object = NULL; - EhSym** syms; - EhSym* sym; - unsigned size; - - info.index = 0; - info.vector = NULL; - EhSymTableMap(table, flush_mappee, (void*)&info); - size = info.index; - - syms = (EhSym**)malloc(sizeof(EhSym*) * size); - info.index = 0; - info.vector = syms; - EhSymTableMap(table, flush_mappee, (void*)&info); - - /* sort */ - qsort(syms, size, sizeof(EhSym*), flush_compare); - - /* dump */ - for (n = 0; n < size; n++) { - sym = syms[n]; - - if (sym->object != object) { - object = sym->object; - - if (object->source != NULL) { - EhSourceFpWrite(object->source, fp); - } - } - - if (sym->state == EH_SYM_INLINE) { - fprintf(fp, "%s %c\n", sym->name, EH_TAG_INLINE); - } else if (object->source != NULL && sym->state == EH_SYM_ZAPPED) { - fprintf(fp, "%s %c\n", sym->name, EH_TAG_ZAPPED); - } else if (object->source != NULL && sym->state == EH_SYM_DEFINED) { - fprintf(fp, "%s %c\n", sym->name, EH_TAG_GLOBAL); - } - } - - free(syms); - - return n; -} - -int djw_debug; -char* djw_test_name; - -int -eh_process_object(Elf* elf, EhObject* object, EhSymTable* table) -{ - Elf32_Shdr * shdr; - Elf32_Ehdr * ehdr; - Elf_Scn * scn; - Elf_Data * shstr_data; - Elf_Data* sym_data = NULL; - Elf_Data* str_data = NULL; - Elf_Data* rel_data[4]; - int nrel_data = 0; - Elf32_Rel* rel_entries; - Elf_Data* rela_data[10]; - int nrela_data = 0; - Elf32_Rela* rela_entries; - unsigned int cnt; - Elf32_Sym* elf_sym; - int i; - int j; - int k; - char* name; - EhSym* sym; - char buf[MAXPATHLEN]; - - /* Obtain the .shstrtab data buffer */ - if (((ehdr = elf32_getehdr(elf)) == NULL) || - ((scn = elf_getscn(elf, ehdr->e_shstrndx)) == NULL) || - ((shstr_data = elf_getdata(scn, NULL)) == NULL)) { - fprintf(stderr, "problems on %s\n", EhObjectGetFilename(object, buf)); - return -1; - } - - /* get the string table */ - for (cnt = 1, scn = NULL; (scn = elf_nextscn(elf, scn)); cnt++) { - if ((shdr = elf32_getshdr(scn)) == NULL) { - fprintf(stderr, "problems on %s, section %d\n", - EhObjectGetFilename(object, buf), cnt); - return -1; - } - -#if 0 - fprintf(stderr, "%s: section %d type %d name %s\n", - EhObjectGetFilename(object, buf), - cnt, - shdr->sh_type, - (char*)shstr_data->d_buf + shdr->sh_name); -#endif - - /* - * Get the string table. - */ - if (shdr->sh_type == SHT_STRTAB && -#ifdef sun - strcmp((char*)shstr_data->d_buf + shdr->sh_name, ".strtab") == 0 && -#endif - cnt != ehdr->e_shstrndx) { - if (str_data != NULL) { - fprintf(stderr, "multiple string tables for %s - bailing\n", - EhObjectGetFilename(object, buf)); - return -1; - } - str_data = elf_getdata(scn, NULL); - } else if (shdr->sh_type == SHT_SYMTAB) { /* look into sym table */ - if (sym_data != NULL) { - fprintf(stderr, "multiple symbol tables for %s - bailing\n", - EhObjectGetFilename(object, buf)); - return -1; - } - sym_data = elf_getdata(scn, NULL); - } else if (shdr->sh_type == SHT_REL) { /* look into rel table */ - if (nrel_data >= 4) { - fprintf(stderr, "too many relocation tables for %s bailing\n", - EhObjectGetFilename(object, buf)); - return -1; - } - rel_data[nrel_data++] = elf_getdata(scn, NULL); - } else if (shdr->sh_type == SHT_RELA) { /* look into rela table */ - if (nrela_data >= 10) { - fprintf(stderr, "too many RELA tables for %s bailing\n", - EhObjectGetFilename(object, buf)); - return -1; - } - rela_data[nrela_data++] = elf_getdata(scn, NULL); - } - } - - if (sym_data == NULL) { - fprintf(stderr, "could not load sym table for %s\n", - EhObjectGetFilename(object, buf)); - return -1; - } - - if (str_data == NULL) { - fprintf(stderr, "could not load string table for %s\n", - EhObjectGetFilename(object, buf)); - return -1; - } - - elf_sym = (Elf32_Sym*)sym_data->d_buf; - - for (i = 0; i < (sym_data->d_size/sizeof(Elf32_Sym)); i++) { - - /* - * We are only interested in globals. - */ - if (ELF32_ST_BIND(elf_sym[i].st_info) != STB_GLOBAL) - continue; - - name = (char *)str_data->d_buf + elf_sym[i].st_name; - - if (djw_test_name != NULL - && strcmp(djw_test_name, name) == 0) { - printf("found %s\n", name); - } - - sym = EhSymTableFind(table, name); - - /* - * Treat inlines as non-globals - */ - if (sym != NULL && sym->state == EH_SYM_INLINE) - continue; - -#if 0 - printf("name = %s value = %d type = %d, info = %d," - " other = %d, size = %d\n", - name, - elf_sym[i].st_value, - ELF32_ST_TYPE(elf_sym[i].st_info), - elf_sym[i].st_info, - elf_sym[i].st_other, - elf_sym[i].st_size); -#endif - - /* defined */ - if (ELFSYM_IS_DEFINED(elf_sym[i])) { - - if (sym != NULL) { - - if (sym->object == NULL) { /* object undefined */ - sym->object = object; - } else if (sym->object->name==eh_unnamed_object) { - - if (object->source != NULL - && - object->source != sym->object->source) { - - fprintf(stderr, - "warning: symbol %s defined in more than one source file\n" - "last time: %s\n" - "this time: %s (ignored)\n", - sym->name, - object->source->name, - sym->object->source->name); - } else { - object->source = sym->object->source; - /* - * Do a global: sym->object = object; - */ - EhSymTableObjectFixup(table, - sym->object, /*old*/ - object); /*new*/ - - } - - } else if (sym->object != object) { - fprintf(stderr, - "warning: symbol %s define in multiple object files\n" - "last time: %s\n" - "this time: %s (ignored)\n", - sym->name, - object->name, - sym->object->name); - } - - sym->state = EH_SYM_DEFINED; - - } else { - sym = EhSymNewDefined(name, object); - EhSymTableInsert(table, sym); - } - - for (k = 0; k < nrel_data; k++) { - int nentries = rel_data[k]->d_size/sizeof(Elf32_Rel); - - rel_entries = (Elf32_Rel*)rel_data[k]->d_buf; - - for (j = 0; j < nentries; j++) { - if (ELF32_R_SYM(rel_entries[j].r_info) == i) { - /* locally referenced */ - sym->nlusers++; - } - } - } - for (k = 0; k < nrela_data; k++) { - int nentries = rela_data[k]->d_size/sizeof(Elf32_Rela); - - rela_entries = (Elf32_Rela*)rela_data[k]->d_buf; - - for (j = 0; j < nentries; j++) { - if (ELF32_R_SYM(rela_entries[j].r_info) == i) { - /* locally referenced */ - sym->nlusers++; - } - } - } - } - - /* Undefined. */ - else if (ELFSYM_IS_UNDEFINED(elf_sym[i])) { - - if (sym == NULL) { - sym = EhSymNewUndefined(name); - EhSymTableInsert(table, sym); - } - sym->ngusers++; - } else { - -#if 1 - printf("what is this: " - "name = %s value = %d type = %d, " - "info = %d, other = %d, size = %d\n", - name, - elf_sym[i].st_value, - ELF32_ST_TYPE(elf_sym[i].st_info), - elf_sym[i].st_info, - elf_sym[i].st_other, - elf_sym[i].st_size); -#endif - ; - }/* type ==... */ - } /* for each symbol */ - - return 0; -} - -int -eh_process_file(char* filename, EhSymTable* table, char* rootdir) -{ - Elf* elf; - Elf* arf; - int fd; - Elf_Cmd cmd; - Elf_Kind e_kind; - EhObject* object; - EhArchive* archive; - Elf_Arhdr* arhdr; - char* name; - int rv = 0; - - if ((fd = open(filename, O_RDONLY)) == -1) { - fprintf(stderr, "error opening %s\n", filename); - return -1; - } - - elf_version(EV_CURRENT); - if ((arf = elf_begin(fd, ELF_C_READ, NULL)) == NULL) { - return -1; - } - - e_kind = elf_kind(arf); - if (e_kind == ELF_K_ELF) { - object = EhObjectNew(filename, rootdir); - rv = eh_process_object(arf, object, table); - - } else if (e_kind == ELF_K_AR) { - - archive = EhArchiveNew(filename, rootdir); - cmd = ELF_C_READ; - -#if 0 - arsyms = elf_getarsym(arf, &narsyms); - - for (i = 0; i < narsyms && arsyms[i].as_name != NULL; i++) { - printf("%s - %d\n", arsyms[i].as_name, arsyms[i].as_off); - } - - arhdr = elf_getarhdr(arf); - for (i = 0; arhdr[i].ar_rawname != NULL; i++) { - - if (arhdr[i].ar_name != NULL) - printf("%s\n", arhdr[i].ar_name); - else - printf("[%s]\n", arhdr[i].ar_rawname); - } -#endif - - rv = 0; - - while ((elf = elf_begin(fd, cmd, arf)) != 0) { - - e_kind = elf_kind(elf); - - if (e_kind != ELF_K_ELF) - continue; - - arhdr = elf_getarhdr(elf); - - if (arhdr != NULL) { - if (arhdr->ar_name != NULL) - name = arhdr->ar_name; - else - name = arhdr->ar_rawname; - } else { - name = eh_unnamed_object; - } - - object = EhObjectNewArchiveObject(archive, name); - rv = eh_process_object(elf, object, table); - - if (rv == -1) - break; - - cmd = elf_next(elf); - elf_end(elf); - } - } - - elf_end(arf); - - close(fd); - - return rv; -} - -static int -eh_dump_unused(EhSym* sym, void* arg) -{ - char buf[MAXPATHLEN]; - - printf(/*"0x%x "*/ "%s %d %d ", /*sym,*/ - sym->name, sym->ngusers, sym->nlusers); - - if (EHSYM_ISINLINE(sym)) - printf("%c ", EH_TAG_INLINE); - else if (EHSYM_ISZAPPED(sym)) - printf("%c ", EH_TAG_ZAPPED); - else if (EHSYM_ISDEFINED(sym)) - printf("%c ", EH_TAG_GLOBAL); - else - printf("%c ", EH_TAG_UNDEFINED); - - if (sym->object != NULL) { - printf("%s ", EhObjectGetFilename(sym->object, buf)); - if (sym->object->source != NULL) { - printf("%s recompilable\n", sym->object->source->name); - } else { - printf("nosource notrecompilable\n"); - } - } else { - printf("noobject nosource notrecompilable\n"); - } - - return 0; -} - -static void -print_dump(EhSymTable* table) -{ - printf("everything\n"); - EhSymTableMap(table, eh_dump_unused, NULL); -} - -typedef struct { - unsigned ndefined; - unsigned nused; /* globally */ - unsigned nundefined; - unsigned nzapped; - unsigned nzapped_nowused; - unsigned ninlined; - unsigned nunlinked; - unsigned ndeadcode; -} SummaryInfo; - -static int -eh_summary_mappee(EhSym* sym, void* arg) { - SummaryInfo* info = (SummaryInfo*)arg; - - if (EHSYM_ISDEFINED(sym)) { - if (sym->ngusers != 0) - info->nused++; - else if (sym->object != NULL && sym->object->nusers == 0) - info->nunlinked++; - else if (sym->nlusers != 0) - info->ndefined++; - else - info->ndeadcode++; - - } else if (EHSYM_ISZAPPED(sym)) { /* one of ours */ - if (sym->ngusers != 0) - info->nzapped_nowused++; - else - info->nzapped++; - } else if (EHSYM_ISINLINE(sym)) { /* one of ours */ - info->ninlined++; - } else { - info->nundefined++; - } - - return 0; -} - -static void -get_summary(EhSymTable* table, SummaryInfo* info) -{ - info->ndefined = 0; - info->nused = 0; - info->nundefined = 0; - info->nzapped = 0; - info->nzapped_nowused = 0; - info->ninlined = 0; - info->nunlinked = 0; - info->ndeadcode = 0; - - EhSymTableMap(table, eh_summary_mappee, info); -} - -static void -print_summary(EhSymTable* table) -{ - SummaryInfo info; - - get_summary(table, &info); - - printf("summary:\n" - "defined and used: %d\n" - "defined but unused globally: %d\n" - "total globals in target: %d\n" - "--------------------------------\n" - "global to statics *: %d\n" - "global to statics (now used): %d\n" - "inlined to statics *: %d\n" - "defined in unlinked objects: %d\n" - "defined but unused (deadcode):%d\n" - "undefined but used: %d\n", - info.nused, - info.ndefined, - (info.nused + info.ndefined), - info.nzapped, - info.nzapped_nowused, - info.ninlined, - info.nunlinked, - info.ndeadcode, - info.nundefined); -} - -typedef struct EhDirMapEntree { - char* dirname; - struct EhDirMapEntree* _next; -} EhDirMapEntree; - -typedef struct EhDirMap { - EhDirMapEntree* head; -} EhDirMap; - -static EhDirMap* -EhDirMapNew(void) -{ - EhDirMap* dm = EH_NEW(EhDirMap); - dm->head = NULL; - return dm; -} - -static void -EhDirMapAddDirectory(EhDirMap* map, char* dirname) -{ - EhDirMapEntree* entree = EH_NEW(EhDirMapEntree); - EhDirMapEntree* foo; - - entree->dirname = strdup(dirname); - entree->_next = NULL; - - if (map->head == NULL) { - map->head = entree; - } else { - for (foo = map->head; foo->_next != NULL; foo = foo->_next) - ; - - foo->_next = entree; - } -} - -static char* -EhDirMapGetLibName(EhDirMap* map, char* name, char* libbuf) -{ - EhDirMapEntree* foo; - struct stat buf; - - for (foo = map->head; foo != NULL; foo = foo->_next) { - sprintf(libbuf, "%s/lib%s.a", foo->dirname, name); - - if (stat(libbuf, &buf) != -1) - return libbuf; - } - - return NULL; -} - -static char* -test_for_global(char* buf) -{ -#ifdef IRIX - if (strncmp(buf, "\t.globl\t", 8) == 0) - return &buf[8]; -#else - if (strncmp(buf, "\t.global ", 9) == 0) - return &buf[9]; -#endif - return NULL; -} - -static char* -test_for_file(char* foo, char* buf) -{ -#ifdef IRIX - char* p; - char* q; - if (strncmp(buf, "\t.file\t", 6) == 0) { - for (p = &buf[6]; *p != '"' && *p != '\0'; p++) - ; - if (*p == '\0') - return NULL; - p++; /* quote */ - q = strchr(p, '"'); - if (q == NULL) - return NULL; - memcpy(foo, p, q - p); - foo[q - p] = '\0'; - return foo; - } -#else - printf("test_for_file() not implemented\n"); -#endif - return NULL; -} - -static int -EhSourceZapFp(EhSource* source, EhSymTable* table, FILE* fpi, FILE* fpo, - unsigned verbosity, unsigned cplusplus) -{ - char* buf = NULL; - char* p; - int nzap = 0; - char* name; - EhSym* sym; - int i_zapped; - EhObject* object = EhObjectNewFromSource(source); - char* filename = source->name; - char* tmp_name; - char foo[256]; - unsigned line_n = 0; - - if (VERBOSITY_DEBUG(verbosity)) - fputs("gts: ", stderr); - - while ((buf = safe_fgets(buf, 4192, fpi)) != NULL) { - - i_zapped = 0; - for (p = buf; *p != '\0' && *p != '\n'; p++) - ; - *p = '\0'; - - if ((tmp_name = test_for_file(foo, buf)) != NULL) { - if (strcmp(tmp_name, filename) != 0) /* not the same file */ - filename = "non local file"; - else - filename = source->name; - } - - else if ((name = test_for_global(buf)) != NULL) { - - sym = EhSymTableFind(table, name); - - /* an inline, we have to treat specially */ - if ((filename != source->name && cplusplus != 0) /* inline now */ - || - (sym != NULL && sym->state == EH_SYM_INLINE)) {/* was inline */ - - if (!sym) { - - sym = EhSymNewInline(name); - - EhSymTableInsert(table, sym); - } - sym->state = EH_SYM_INLINE; /* just make sure */ - - if (fpo != NULL) /* always zap inlines we see */ - fputs(" # gts", fpo); - - } else { /* a real global */ - - if (fpo != NULL && sym != NULL && EHSYM_ISZAPPED(sym)) { - if (VERBOSITY_DEBUG(verbosity)) { - fprintf(stderr, "%s ", &buf[8]); - } - nzap++; - - if (fpo != NULL) - fputs(" # gts", fpo); - } - - if (sym != NULL) { - if (sym->object == NULL) { - sym->object = object; - } else if (sym->object != object) { - sym->object->source = source; - EhSymTableObjectFixup(table, object, sym->object); - object = sym->object; - } - } else { /* install a new one */ - - sym = EhSymNewDefined(name, object); - - EhSymTableInsert(table, sym); - } - - } - } - - if (fpo != NULL) { - fputs(buf, fpo); - fputc('\n', fpo); - } - line_n++; - } - - if (VERBOSITY_DEBUG(verbosity)) - fputc('\n', stderr); - - return nzap; -} - -static void -print_command(char* command, char** args, unsigned verbosity) -{ - int i; - FILE* fp = stderr; - if (!VERBOSITY_USER(verbosity)) - return; - - fprintf(fp, "%s: ", command); - for (i = 0; args[i]; i++) { - fprintf(fp, "%s ", args[i]); - } - fprintf(fp, "\n"); -} - -static int -do_command(char* label, char** args, unsigned verbosity) -{ - int status; - pid_t child_pid; - char* file = args[0]; - - print_command(label, args, verbosity); - - if ((child_pid = fork()) == -1) { - fprintf(stderr, "could not fork: "); - perror(NULL); - return -1; - } - - if (child_pid == 0) { /* i am the child */ - if (execvp(file, args) == -1) { - fprintf(stderr, "could not exec %s: ", file); - perror(NULL); - exit(3); - } - /*NOTREACHED*/ - } - - if (waitpid(child_pid, &status, 0) == -1) { - fprintf(stderr, "wait on %s failed: ", file); - perror(NULL); - return -1; - } - - return WEXITSTATUS(status); -} - -static char* -suffix_name(char* s) -{ - char* p; - - if ((p = strrchr(s, '.')) != NULL) - return p; - else - return ""; -} - -static char base_name_buf[MAXPATHLEN]; - -static char* -base_name(char* s) -{ - char* p; - - if ((p = strrchr(s, '.')) != NULL) { - memcpy(base_name_buf, s, p - s); - base_name_buf[p - s] = '\0'; - s = base_name_buf; - } - return s; -} - -static char* -file_base_name(char *s) -{ - char* p; - - s = base_name(s); - - if ((p = strrchr(s, '/')) != NULL) - s = &p[1]; - - return s; -} -static int -EhSourceCompile(EhSource* source, - EhSymTable* table, - unsigned verbosity, - unsigned do_compile, - unsigned do_zap, - unsigned do_assem) -{ - char* filename = source->name; - char** opts = source->cc_args; - char asname[MAXPATHLEN]; - char o_asname[MAXPATHLEN]; - char* cc_opts[256]; - unsigned i = 0; - unsigned j = 0; - FILE* in_fp; - FILE* out_fp; - int status; - int nzap = 0; - char* save_prefix = NULL; - unsigned do_dash_s = (do_zap != 0 || save_prefix != NULL); - char* cc_command; - char* use_savefile = NULL; - struct timeval start_time; - struct timeval end_time; -#ifdef DEBUG_djw - char savebuf[1024]; -#endif - unsigned is_cplusplus = 0; - -#ifdef LINUX - gettimeofday(&start_time,NULL); -#else - gettimeofday(&start_time); -#endif - - /* munge file */ -#ifdef HANDLES_DASHSO - if (source->target_object != NULL) - strcpy(asname, base_name(source->target_object)); - else -#endif - strcpy(asname, file_base_name(filename)); - strcat(asname, ".s"); - - strcpy(o_asname, asname); - strcat(o_asname, ".gts_tmp"); - - if (strcmp(suffix_name(filename), ".cpp") == 0) { - cc_command = CCC_COMMAND; - is_cplusplus = 1; - } else if (strcmp(suffix_name(filename), ".s") == 0) { - do_compile = FALSE; - cc_command = CC_COMMAND; - } else { - cc_command = CC_COMMAND; - } - - if (do_compile) { - - j = 0; - cc_opts[j++] = cc_command; - cc_opts[j++] = "-c"; - - if (do_dash_s) { - cc_opts[j++] = "-S"; -#ifdef HANDLES_DASHSO - if (source->target_object != NULL) { - cc_opts[j++] = "-o"; - cc_opts[j++] = asname; - } -#endif - } else if (source->target_object != NULL) { - cc_opts[j++] = "-o"; - cc_opts[j++] = source->target_object; - } - - i = 0; - while (opts[i] != NULL) - cc_opts[j++] = opts[i++]; - - cc_opts[j++] = filename; - cc_opts[j] = NULL; - - if ((status = do_command("compile", cc_opts, verbosity)) != 0) { - fprintf(stderr, "compile failed (returned %d)\n", status); - return -1; - } - - if (!do_dash_s) - return 0; - } - - /* - * Now we have a foo.s file, what do we do with it? - */ - if (do_zap > 1) { - - if (use_savefile == NULL) - use_savefile = asname; - - if ((in_fp = fopen(use_savefile, "r")) == NULL) { - fprintf(stderr, "could not open %s for reading\n", asname); - return -1; - } - - if ((out_fp = fopen(o_asname, "w")) == NULL) { - fprintf(stderr, "could not open %s for writing\n", o_asname); - return -1; - } - - j = 0; - cc_opts[j++] = "gts"; - cc_opts[j++] = asname; - cc_opts[j++] = o_asname; - cc_opts[j++] = NULL; - print_command("gts", cc_opts, verbosity); - - nzap = EhSourceZapFp(source, table, in_fp, out_fp, verbosity, is_cplusplus); - - fclose(in_fp); - fclose(out_fp); - - j = 0; - cc_opts[j++] = "rename"; - cc_opts[j++] = o_asname; - cc_opts[j++] = asname; - cc_opts[j++] = NULL; - print_command("rename", cc_opts, verbosity); - -#ifdef DEBUG_djw - strcpy(savebuf, "gts_pre_"); - strcat(savebuf, asname); - rename(asname, savebuf); -#endif - - if (rename(o_asname, asname) == -1) { - fprintf(stderr, "could not rename %s\n", o_asname); - return -1; - } - - } else if (do_zap > 0) { /* audit only */ - - if ((in_fp = fopen(asname, "r")) == NULL) { - fprintf(stderr, "could not open %s for reading\n", asname); - return -1; - } - - j = 0; - cc_opts[j++] = "audit"; - cc_opts[j++] = asname; - cc_opts[j++] = NULL; - print_command("audit", cc_opts, verbosity); - - nzap = EhSourceZapFp(source, table, in_fp, NULL, verbosity, is_cplusplus); - - fclose(in_fp); - } - - if (do_assem) { - i = 0; - j = 0; - cc_opts[j++] = AS_COMMAND; - cc_opts[j++] = "-c"; - - if (source->target_object != NULL) { - cc_opts[j++] = "-o"; - cc_opts[j++] = source->target_object; - } - - while (opts[i] != NULL) - cc_opts[j++] = opts[i++]; - - cc_opts[j++] = asname; - cc_opts[j] = NULL; - - if ((status = do_command("assemble", cc_opts, verbosity)) != 0) { - - unlink(asname); - - fprintf(stderr, - "gtscc of %s failed (exit status = %d), reverting to %s:\n", - filename, - status, - cc_command); - - i = 0; - j = 0; - cc_opts[j++] = cc_command; - cc_opts[j++] = "-c"; - - if (source->target_object != NULL) { - cc_opts[j++] = "-o"; - cc_opts[j++] = source->target_object; - } - - for (; opts[i]; i++, j++) - cc_opts[j] = opts[i]; - - cc_opts[j++] = filename; - cc_opts[j] = NULL; - - if ((status = do_command("fix-compile", cc_opts, verbosity)) != 0) - return -1; - - return 0; - } - } - - if (save_prefix != NULL && save_prefix[0] != '\0') { - - sprintf(o_asname, save_prefix, file_base_name(filename)); - - j = 0; - cc_opts[j++] = "rename"; - cc_opts[j++] = asname; - cc_opts[j++] = o_asname; - cc_opts[j++] = NULL; - print_command("savefile", cc_opts, verbosity); - - if (rename(asname, o_asname) == -1) { - fprintf(stderr, "could not rename %s to %s - sorry\n", - asname, o_asname); - return -1; - } - - if (source->as_savefile != NULL) - free(source->as_savefile); - source->as_savefile = strdup(o_asname); - } else { - - j = 0; - cc_opts[j++] = "unlink"; - cc_opts[j++] = asname; - cc_opts[j++] = NULL; - print_command("unlink", cc_opts, verbosity); - -#ifdef DEBUG_djw - strcpy(savebuf, "gts_post_"); - strcat(savebuf, asname); - rename(asname, savebuf); -#else - unlink(asname); -#endif - } - -#ifdef LINUX - gettimeofday(&end_time,NULL); -#else - gettimeofday(&end_time); -#endif - - source->compile_time = ((end_time.tv_sec - start_time.tv_sec) * 1000) + - ((end_time.tv_usec - start_time.tv_usec) / 1000); - - return nzap; -} - -static char target_buf[MAXPATHLEN]; /* this will go away with rel source */ - -static char* -EhSourceGetTarget(EhSource* source) -{ - if (source->target_object != NULL) - return source->target_object; - - strcpy(target_buf, base_name(source->name)); - strcat(target_buf, ".o"); - - return target_buf; -} - -static int -EhArchiveUpdate(EhArchive* archive, char* target, char* rootdir, - unsigned verbosity) -{ - char* args[8]; - unsigned nargs; - int status; - char pathname[MAXPATHLEN]; - - pathname[0] = '\0'; - if (rootdir != NULL) { - strcat(pathname, rootdir); - strcat(pathname, "/"); - } - strcat(pathname, archive->name); - -#if 0 - nargs = 0; - args[nargs++] = AR_COMMAND; - args[nargs++] = "dc"; - args[nargs++] = pathname; - args[nargs++] = target; - args[nargs++] = NULL; - - if ((status = do_command("delete from archive", args, verbosity)) != 0) { - fprintf(stderr, "archive: %s delete %s failed (status = %d)\n", - pathname, - target); - return -1; - } -#endif - - nargs = 0; - args[nargs++] = AR_COMMAND; - args[nargs++] = AR_OPTIONS; - args[nargs++] = pathname; - args[nargs++] = target; - args[nargs++] = NULL; - - if ((status = do_command("archive", args, verbosity)) != 0) { - fprintf(stderr, "archive: %s <- %s failed (status = %d)\n", - pathname, - target); - return -1; - } - - return 0; -} - -static int -EhObjectRebuild(EhObject* object, - EhSymTable* table, - unsigned verbosity, - char* rootdir) -{ - EhSource* source = object->source; - char cwd[MAXPATHLEN]; - char fullpath[MAXPATHLEN]; - int rv = 0; - int do_chdir = 0; - - if (!source) { - fprintf(stderr, - "wanted to recompile %s, but I don't how\n", - object->name); - return -1; - } - -#if 0 - if (VERBOSITY_USER(verbosity)) -#endif - fprintf(stderr, "recompiling %s\n", source->name); - - /* - * Check to see if we need to chdir - */ - if (source->directory != NULL) { - if (getcwd(cwd, sizeof(cwd)) == NULL) { - fprintf(stderr, "cannot get pwd: cannot compile\n"); - return -1; - } - - make_relative_pathname(fullpath, cwd, rootdir); - - if (strcmp(fullpath, source->directory) != 0) { - fullpath[0] = '\0'; - if (rootdir != NULL) { - strcat(fullpath, rootdir); - strcat(fullpath, "/"); - } - strcat(fullpath, source->directory); - - if (chdir(fullpath) == -1) { - fprintf(stderr, "cannot chdir - can't compile\n"); - return -1; - } - do_chdir++; - } - } - - rv = EhSourceCompile(source, - table, - verbosity, - TRUE, /* compile */ - 2, /* do zap */ - TRUE); /* do assem */ - - if (do_chdir) { - if (chdir(cwd) == -1) { - fprintf(stderr, "cannot chdir - this will be very confused\n"); - return -1; - } - } - - if (rv == -1) { - fprintf(stderr, "recompiling %s failed\n", source->name); - return -1; - } - - /* do archive */ - fullpath[0] = '\0'; - if (rootdir != NULL) { - strcat(fullpath, rootdir); - strcat(fullpath, "/"); - } - - if (source->directory != NULL) - strcat(fullpath, source->directory); - - strcat(fullpath, "/"); - strcat(fullpath, EhSourceGetTarget(source)); - - if (object->archive != NULL) { - if (EhArchiveUpdate(object->archive, fullpath, rootdir, - verbosity) == -1) - return -1; - } - - /* do install */ -#if 0 - if (rv != -1) { - } -#endif - - return rv; -} - -static int -object_nusers_mappee(EhSym* sym, void* arg) -{ - if (sym->object != NULL) - sym->object->nusers += sym->ngusers; - return 0; -} - -typedef struct { - EhObject* recompile_list; - unsigned recompile_count; - unsigned recompile_wish_count; - unsigned unzap_count; - unsigned zap_count; -} RecompileInfo; - -static int -recompile_init_mappee(EhSym* sym, void* arg) -{ - RecompileInfo* info = (RecompileInfo*)arg; - - if (EHSYM_ISZAPPED(sym) && sym->ngusers != 0) { - if (EH_OBJECT_CANBUILD(sym->object)) { - sym->state = EH_SYM_DEFINED; - if (sym->object->_recompile == NULL) { - sym->object->_recompile = info->recompile_list; - info->recompile_list = sym->object; - info->recompile_count++; - } - info->unzap_count++; - sym->object->_needs_unzap++; - } - info->recompile_wish_count++; - } - else if (EHSYM_ISDEFINED(sym) /* it's defined */ - && sym->ngusers == 0 /* there are no global users */ - && sym->nlusers != 0 /* BUT, ther are local users */ - && sym->object->nusers != 0) { /* object is linked */ - - if (EH_OBJECT_CANBUILD(sym->object)) { - sym->state = EH_SYM_ZAPPED; - if (sym->object->_recompile == NULL) { - sym->object->_recompile = info->recompile_list; - info->recompile_list = sym->object; - info->recompile_count++; - } - info->zap_count++; - } - info->recompile_wish_count++; - } - - return 0; -} - -static char** recompile_compare_prefs; -static char** recompile_compare_unprefs; - -static unsigned -match_prefs(char* candidate, char** prefs) -{ - unsigned n; - - for (n = 0; prefs[n] != NULL; n++) { - char* pref = prefs[n]; - unsigned len = strlen(pref); - if (strncmp(pref, candidate, len) == 0) - return n; /* cool */ - } - return (unsigned)-1; /* big! */ -} - -static int -recompile_compare(const void* ap, const void* bp) -{ - EhObject** ax = (EhObject**)ap; - EhObject** bx = (EhObject**)bp; - EhObject* obj_a = *ax; - EhObject* obj_b = *bx; - EhSource* src_a = obj_a->source; - EhSource* src_b = obj_b->source; - unsigned matcha; - unsigned matchb; - int foo; - - if (obj_a->_needs_unzap == 0 && obj_b->_needs_unzap != 0) - return -1; - if (obj_a->_needs_unzap != 0 && obj_b->_needs_unzap == 0) - return 1; - - if (src_a == NULL && src_b != NULL) - return 1; - if (src_a != NULL && src_b == NULL) - return -1; - if (src_a == src_b) - return 0; - - if (recompile_compare_unprefs != NULL - && src_a->directory != NULL && src_b->directory != NULL) { - - matcha = match_prefs(src_a->directory, recompile_compare_unprefs); - matchb = match_prefs(src_b->directory, recompile_compare_unprefs); - - if (matcha > matchb) /* greater is good */ - return -1; - if (matcha < matchb) - return 1; - } - - if (recompile_compare_prefs != NULL - && src_a->directory != NULL && src_b->directory != NULL) { - - matcha = match_prefs(src_a->directory, recompile_compare_prefs); - matchb = match_prefs(src_b->directory, recompile_compare_prefs); - - if (matcha > matchb) /* greater is bad */ - return 1; - if (matcha < matchb) - return -1; - } - - /* else same directory probably */ - foo = strcmp(src_a->name, src_b->name); - - if (foo < 0) - return -1; - if (foo > 0) - return 1; - - return 0; -} - -static int -do_recompilation(EhSymTable* table, char* gts_file, unsigned max_globals, - char** prefs, char** unprefs, - char* rootdir, unsigned verbosity) -{ - SummaryInfo s_info; - RecompileInfo info; - unsigned size; - unsigned n; - EhObject* object; - EhObject** recompiles; - unsigned delta; - int rv; - unsigned nzaps; - EhObject dummy; /* just marks the end of the recomp list */ - time_t eta; - - get_summary(table, &s_info); - - if ((s_info.nused + s_info.ndefined) <= max_globals) { - if (VERBOSITY_USER(verbosity)) - fprintf(stderr, - "number of globals <= requested max, skipping recompilation\n"); - return 0; - } - - /* Init recompilation. */ - info.recompile_list = &dummy; /* cannot use NULL, because syms test that */ - info.recompile_count = 0; - info.recompile_wish_count = 0; - info.unzap_count = 0; - info.zap_count = 0; - EhSymTableMap(table, recompile_init_mappee, (void*)&info); - size = info.recompile_count; - - recompiles = (EhObject**)malloc(sizeof(EhObject*) * size); - - /* install */ - n = 0; - for (object = info.recompile_list; - object != &dummy; - object = object->_recompile) { - recompiles[n++] = object; - } - - /* sort */ - recompile_compare_prefs = prefs; - recompile_compare_unprefs = unprefs; - qsort(recompiles, size, sizeof(EhObject*), recompile_compare); - - /* - * sorted ! - * less recompile the first n, n = ndefined - max - */ - delta = (s_info.nused + s_info.ndefined) - max_globals; - - if (delta > info.zap_count) { - fprintf(stderr, - "WARNING: there too many globals (%d/%d fixables).\n" - " I don't think I can fix this, but I'll try.\n" - " You might get lucky.\n", - info.zap_count, - delta); - } - - if (VERBOSITY_USER(verbosity)) - fprintf(stderr, "scheduling recompilation targets:\n"); - - eta = 0; - for (n = 0; n < size; n++) { - char* cname = "unknown"; - object = recompiles[n]; - if (object->source != NULL) { - cname = object->source->name; - eta += object->source->compile_time; - } - - if (VERBOSITY_DEBUG(verbosity)) - fprintf(stderr, "object %s from source %s\n", object->name, cname); - } - -#if 0 - if (VERBOSITY_USER(verbosity)) -#endif - fprintf(stderr, "gts-ing %d symbols, eta = %d minutes\n", delta, - eta/(60*1000)); - - if (gts_file != NULL) { - FILE* zap_fp; - if ((zap_fp = fopen(gts_file, "w")) == NULL) { - perror(0); - fprintf(stderr, - "WARNING: could not open the gtscc db file %s.\n" - " I will continue with the recompilation, but\n" - " if you recompile any of the files I touched\n" - " I'll have to recompile them after you!\n", - gts_file); - } else { - - EhSymTableFpDump(table, zap_fp); - - fclose(zap_fp); - } - } - - for (n = 0, nzaps = 0; n < size && nzaps < delta; n++) { - - object = recompiles[n]; - rv = EhObjectRebuild(object, table, verbosity, rootdir); - - if (rv == -1) - return -1; - - nzaps += rv; - - object->_recompile = NULL; /* clean up now */ - } - - if (nzaps < delta) { - fprintf(stderr, - "WARNING: I wanted to gts %d symbols, but only managed\n" - " to get %d of them.\n" - " Your link may fail with GOT errors.\n", - delta, - nzaps); - } - - free(recompiles); - - return n; -} - -typedef struct FileList -{ - char* name; - struct FileList* next; -} FileList; - -static FileList* -fileListFind(FileList* list, char* name) -{ - FileList* foo; - - for (foo = list; foo != NULL; foo = foo->next) { - if (strcmp(name, foo->name) == 0) - return foo; - } - return NULL; -} - -static FileList* -fileListAppend(FileList** list_a, char* name) -{ - FileList* list = *list_a; - FileList* foo; - FileList* last; - - for (foo = list, last = NULL; foo != NULL; last = foo, foo = foo->next) - ; - - if (last == NULL) { - foo = EH_NEW(FileList); - foo->next = NULL; - foo->name = strdup(name); - *list_a = foo; - } else { - foo = EH_NEW(FileList); - foo->next = NULL; - foo->name = strdup(name); - last->next = foo; - } - - return *list_a; -} - -#if 0 -static FileList* c_list; -#endif -static FileList* o_list; - -#if 0 -static char* -EhSourceAdjustPathname(EhSource* source, char* rootdir) -{ - char buf[MAXPATHLEN]; - char buf2[MAXPATHLEN]; - char* p; - char* q; - char* filename = source->name; - - if (getcwd(buf, sizeof(buf)) == NULL) { - fprintf(stderr, "cannot get pwd\n"); - return NULL; - } - - strcat(buf, "/"); - strcat(buf, filename); - - if (rootdir == NULL) { - filename = buf; - } else { - if (realpath(buf, buf2) == NULL) { - fprintf(stderr, "realpath() failed: %s\n", buf2); - return NULL; - } - - if (realpath(rootdir, buf) == NULL) { - fprintf(stderr, "realpath() failed: %s\n", buf); - return NULL; - } - strcat(buf, "/"); - - for (p = buf, q = buf2; *p == *q; p++, q++) - ; - - filename = q; - } - - free(source->name); - source->name = strdup(filename); - - return source->name; -} -#endif - -static unsigned -katoi(char *buf) -{ - unsigned base = 1; - char* s; - - for (s = buf; isdigit(*s); s++) - ; - - if (*s == 'k' || *s == 'K') - base = 1024; - - *s = '\0'; - - return base * atoi(buf); -} - -static void -usage(void) -{ - fprintf(stderr, - "Usage:\n" - "as a compiler:\n" - "gtscc [gtscc_options] [compiler_options] -c file.c file.cpp ...\n" - "gtscc_options:\n" - "-gtsfile the gts database file (use this)\n" - "-gtszapsymbol convert symbol \n" - "-gtsnozapsymbol don't convert symbol \n" - "-gtsrootdir the root for the tree (use this)\n" - "-gtsverbose be more verbose (3 levels)\n" - "-gtsnozap don't convert globals to statics\n" - "-gtsnoupdate don't update the database file\n" - "as a linker:\n" - "gtscc [gtscc_options] [linker_options] file.o ... libxx.a ...\n" - "gtscc_options:\n" - "-gtsfile the gts database file (use this)\n" - "-gtszapsymbol convert symbol \n" - "-gtsnozapsymbol don't convert symbol \n" - "-gtsrootdir the root for the tree (use this)\n" - "-gtspref please recompile these paths first\n" - "-gtsunpref please try to avoid recompiling these\n" - "-gtsverbose be more verbose (3 levels)\n" - "-gtssummary print a summary of global usage\n" - "-gtsdump print a detailed listing of all symbols\n" - "-gtsmaxglobals [k] maximum globals allowed in target\n" - "-gtsnorecompile don't do the normal recompilation\n" - "-gtsnolink don't call linker after recompilation\n" - "-gtsnoupdate don't update the database file\n" - "-help print this\n" - ); -} - -int -main(int argc, char** argv) -{ - EhSymTable* table = EhSymTableNew(1000); - EhSym* sym; - FILE* zap_fp; - unsigned n = 0; - unsigned verbosity = 0; - char* arg_buf[256]; - unsigned nargs = 0; - EhDirMap* dmap = EhDirMapNew(); - unsigned do_dump = 0; - unsigned do_summary = 0; - unsigned do_link = 1; - unsigned in_link = 1; - unsigned do_audit = 1; - unsigned do_zap = 1; - unsigned do_assem = 1; - unsigned do_recompile = 1; - unsigned do_collect = 1; - char* name; - char* saveprefix = NULL; - char* rootdir = NULL; - int rv; - EhSource* source = NULL; - char* gts_file = NULL; - char* path_prefs[32]; - unsigned npath_prefs = 0; - char* path_un_prefs[32]; - unsigned npath_un_prefs = 0; - char* suffix; - unsigned max_globals = DEFAULT_MAX_GLOBALS; - FileList* list; - - if (elf_version(EV_CURRENT) == EV_NONE) { - fprintf(stderr, "something losing about your elf lib - sorry!\n"); - return 3; - /* library out of date */ - /* recover from error */ - } - - arg_buf[nargs] = NULL; - - for (n = 1; n < argc; n++) { - - if (strcmp(argv[n], "-help") == 0) { - usage(); - return 0; - } else if (strcmp(argv[n], "-gtssummary") == 0) { - do_summary = 1; - } else if (strcmp(argv[n], "-gtsdump") == 0) { - do_dump = 1; - } else if (strcmp(argv[n], "-gtsnorecompile") == 0) { - do_recompile = 0; - } else if (strcmp(argv[n], "-gtsnolink") == 0) { - do_link = 0; - } else if (strcmp(argv[n], "-gtsverbose") == 0) { - verbosity++; - } else if (strcmp(argv[n], "-gtsnoupdate") == 0) { - do_collect = 0; - } else if (strcmp(argv[n], "-gtsnoaudit") == 0) { - do_audit = 0; - } else if (strcmp(argv[n], "-gtsnozap") == 0) { - do_zap = 0; - } else if (strcmp(argv[n], "-gtsrootdir") == 0) { - if (argc < n+2) { - fprintf(stderr, "-gtsrootdir requires an argument\n"); - usage(); - return 2; - } - rootdir = argv[n+1]; - n++; - } else if (strcmp(argv[n], "-gtsdebugsym") == 0) { - if (argc < n+2) { - fprintf(stderr, "-gtsdebugsym requires an argument\n"); - usage(); - return 2; - } - djw_test_name = argv[n+1]; - n++; - } else if (strcmp(argv[n], "-gtsmaxglobals") == 0) { - if (argc < n+2) { - fprintf(stderr, "-gtsmaxglobals requires an argument\n"); - usage(); - return 2; - } - max_globals = katoi(argv[n+1]); - n++; - - } else if (strcmp(argv[n], "-gtspref") == 0) { - if (argc < n+2) { - fprintf(stderr, "-gtspref requires an argument\n"); - usage(); - return 2; - } - path_prefs[npath_prefs++] = argv[n+1]; - path_prefs[npath_prefs] = NULL; - n++; - - } else if (strcmp(argv[n], "-gtsunpref") == 0) { - if (argc < n+2) { - fprintf(stderr, "-gtsunpref requires an argument\n"); - usage(); - return 2; - } - path_un_prefs[npath_un_prefs++] = argv[n+1]; - path_un_prefs[npath_un_prefs] = NULL; - n++; - - } else if (strcmp(argv[n], "-gtssaveprefix") == 0) { - if (argc < n+2) { - fprintf(stderr, "-gtssaveprefix requires an argument\n"); - usage(); - return 2; - } - saveprefix = argv[n+1]; - n++; - - } else if (strcmp(argv[n], "-gtsfile") == 0) { - - struct stat sbuf; - - if (argc < n+2) { - fprintf(stderr, "-gtsfile requires an argument\n"); - usage(); - return 2; - } - - gts_file = argv[n+1]; - - if (stat(gts_file, &sbuf) == -1) { - fprintf(stderr, - "warning: %s does not exist, will be created\n", - gts_file); - } else { - - if ((zap_fp = fopen(gts_file, "r")) == NULL) { - fprintf(stderr, "you lose cannot open %s\n", gts_file); - usage(); - return 2; - } - - if (EhSymTableFpLoad(table, zap_fp) == -1) { - fprintf(stderr, - "error: failed reading symbols from gtsfile %s\n", - argv[n+1]); - usage(); - return 2; - } - - fclose(zap_fp); - } - - n++; - - } else if (strcmp(argv[n], "-gtszapsymbol") == 0) { - if (argc < n+2) { - fprintf(stderr, "-gtszapsymbol requires an argument\n"); - usage(); - return 2; - } - - EhSymTableSetSymbolState(table, argv[n+1], EH_SYM_ZAPPED); - n++; - - } else if (strcmp(argv[n], "-gtsnozapsymbol") == 0) { - if (argc < n+2) { - fprintf(stderr, "-gtsnozapsymbol requires an argument\n"); - usage(); - return 2; - } - - EhSymTableSetSymbolState(table, argv[n+1], EH_SYM_DEFINED); - n++; - - } else if (strcmp(argv[n], "-gtsname") == 0) { - if (argc < n+2) { - fprintf(stderr, "-gtsname requires an argument\n"); - usage(); - return 2; - } - - sym = EhSymTableFind(table, argv[n+1]); - if (!sym) - sym = EhSymNewRandomZap(argv[n+1]); - n++; - do_audit = 1; - - } else if (strcmp(argv[n], "-c") == 0) { /* do not link */ - in_link = 0; - do_link = 0; - } else if (strcmp(argv[n], "-S") == 0) { /* do not assem */ - do_assem = 0; - } else if (strcmp(argv[n], "-o") == 0) { /* parse through */ - arg_buf[nargs++] = argv[n++]; - arg_buf[nargs++] = argv[n]; - arg_buf[nargs] = NULL; - } else if (strcmp((suffix = suffix_name(argv[n])), ".cpp") == 0 - || - strcmp(suffix, ".c") == 0 - || - strcmp(suffix, ".s") == 0) { - char pathname[MAXPATHLEN]; - - make_relative_pathname(pathname, ".", rootdir); - - source = EhSourceNew(argv[n], arg_buf, pathname); - - rv = EhSourceCompile(source, - table, - verbosity, - TRUE, /* compile, .s files ignore anyway */ - (do_audit + do_zap), - do_assem); - if (rv == -1) - return 1; - -#if 0 - EhSourceAdjustPathname(source, rootdir); -#endif - - } else if (strcmp(suffix, ".o") == 0 || strcmp(suffix, ".a") == 0) { - - if (fileListFind(o_list, argv[n]) == NULL) { - fileListAppend(&o_list, argv[n]); - } else { - fprintf(stderr, - "%s repeated on command line - ignored\n", - argv[n]); - } - arg_buf[nargs++] = argv[n]; - arg_buf[nargs] = NULL; - - } else if (strncmp(argv[n], "-L", 2) == 0) { - EhDirMapAddDirectory(dmap, &argv[n][2]); - } else if (strncmp(argv[n], "-l", 2) == 0) { - char pathbuf[MAXPATHLEN]; - name = EhDirMapGetLibName(dmap, &argv[n][2], pathbuf); - if (name != NULL) { - if (fileListFind(o_list, name) == NULL) { - fileListAppend(&o_list, name); - } else { - fprintf(stderr, - "%s repeated on command line - ignored\n", - name); - } - } else { - fprintf(stderr, - "unable to resolve library reference %s - ignoring\n", - argv[n]); - } - arg_buf[nargs++] = argv[n]; - arg_buf[nargs] = NULL; - } else { - arg_buf[nargs++] = argv[n]; - arg_buf[nargs] = NULL; - } - } - - /* - * Analyse objects. - */ - if (o_list != NULL) { - for (list = o_list; list != NULL; list = list->next) { - - if (eh_process_file(list->name, table, rootdir)) { - fprintf(stderr, "oops we died around %s\n", list->name); - return 1; - } - } - - /* look for unused objects */ - EhSymTableMap(table, object_nusers_mappee, 0); - } - - if (do_summary) { - print_summary(table); - } - - if (do_dump) { - print_dump(table); - } - - if (!in_link && gts_file != NULL) { - FILE* zap_fp; - if ((zap_fp = fopen(gts_file, "w")) == NULL) { - perror(0); - usage(); - return 2; - } - - EhSymTableFpDump(table, zap_fp); - fclose(zap_fp); - return 0; - } - - /* - * Now the fun really starts. - */ - if (do_recompile) { - char** pp = NULL; - char** up = NULL; - - if (npath_prefs > 0) - pp = path_prefs; - - if (npath_un_prefs > 0) - up = path_un_prefs; - - if (!do_collect) - gts_file = NULL; - - rv = do_recompilation(table, gts_file, max_globals, pp, up, rootdir, - verbosity); - if (rv == -1) - return 1; - } - - /* - * Finally. - */ - if (do_link) { - - int status; - - arg_buf[nargs+1] = NULL; - for (n = nargs; n > 0; n--) - arg_buf[n] = arg_buf[n-1]; - arg_buf[0] = LD_COMMAND; - - status = do_command("link", arg_buf, verbosity); - - if (status == -1) - return 3; - else - return status; - } - - return 0; -} diff --git a/toolkit/mozapps/installer/packager.mk b/toolkit/mozapps/installer/packager.mk index 1f8e0bcb27f1..28ba832ddf5a 100644 --- a/toolkit/mozapps/installer/packager.mk +++ b/toolkit/mozapps/installer/packager.mk @@ -505,7 +505,6 @@ endif # !CROSS_COMPILE NO_PKG_FILES += \ core \ bsdecho \ - gtscc \ js \ js-config \ jscpucfg \ From c7acb8556a7e496632093340f9d4f554b6f5dc7e Mon Sep 17 00:00:00 2001 From: Oleg Romashin Date: Fri, 19 Aug 2011 12:56:24 +0200 Subject: [PATCH 08/71] Bug 679733 - Widget Qt should send system notifications (display, taskswitcher, flight modes); f=azakai+jbosch r=dougt --- toolkit/xre/Makefile.in | 3 + toolkit/xre/nsNativeAppSupportQt.cpp | 95 ++++++++++++++++++++++------ toolkit/xre/nsNativeAppSupportQt.h | 79 +++++++++++++++++++++++ widget/src/qt/mozqwidget.h | 18 +++++- 4 files changed, 176 insertions(+), 19 deletions(-) create mode 100644 toolkit/xre/nsNativeAppSupportQt.h diff --git a/toolkit/xre/Makefile.in b/toolkit/xre/Makefile.in index 0082e448eb47..9c1e49fdaa6c 100644 --- a/toolkit/xre/Makefile.in +++ b/toolkit/xre/Makefile.in @@ -102,6 +102,9 @@ ifeq ($(MOZ_WIDGET_TOOLKIT),gtk2) CPPSRCS += nsNativeAppSupportUnix.cpp else ifeq ($(MOZ_WIDGET_TOOLKIT),qt) +MOCSRCS += moc_nsNativeAppSupportQt.cpp + $(NULL) +CPPSRCS += $(MOCSRCS) CPPSRCS += nsNativeAppSupportQt.cpp CPPSRCS += nsQAppInstance.cpp EXPORTS += nsQAppInstance.h diff --git a/toolkit/xre/nsNativeAppSupportQt.cpp b/toolkit/xre/nsNativeAppSupportQt.cpp index fe9b9075c17f..4e2ff58a299b 100644 --- a/toolkit/xre/nsNativeAppSupportQt.cpp +++ b/toolkit/xre/nsNativeAppSupportQt.cpp @@ -37,33 +37,92 @@ * ***** END LICENSE BLOCK ***** */ #include -#include "nsNativeAppSupportBase.h" -#include "nsString.h" +#include "mozilla/ipc/GeckoChildProcessHost.h" +#include "nsNativeAppSupportQt.h" +#include "nsCOMPtr.h" +#include "nsIObserverService.h" +#include "mozilla/Services.h" +#include -#ifdef MOZ_ENABLE_LIBCONIC -#include -#endif - -#if (MOZ_PLATFORM_MAEMO == 5) -#include -#endif - -class nsNativeAppSupportQt : public nsNativeAppSupportBase +#ifdef MOZ_ENABLE_QMSYSTEM2 +void +nsNativeAppSupportQt::activityChanged(MeeGo::QmActivity::Activity activity) { -public: - NS_IMETHOD Start(PRBool* aRetVal); - NS_IMETHOD Stop(PRBool* aResult); -#if (MOZ_PLATFORM_MAEMO == 5) - // Osso context must be initialized for maemo5 otherwise we will be killed in ~20 seconds - osso_context_t *m_osso_context; + nsCOMPtr os = mozilla::services::GetObserverService(); + if (!os) + return; + + if (MeeGo::QmActivity::Inactive == activity) { + os->NotifyObservers(nsnull, "system-idle", nsnull); + } else { + os->NotifyObservers(nsnull, "system-active", nsnull); + } +} + +void +nsNativeAppSupportQt::displayStateChanged(MeeGo::QmDisplayState::DisplayState state) +{ + nsCOMPtr os = mozilla::services::GetObserverService(); + if (!os) + return; + + switch (state) { + case MeeGo::QmDisplayState::On: + os->NotifyObservers(nsnull, "system-display-on", nsnull); + break; + case MeeGo::QmDisplayState::Off: + os->NotifyObservers(nsnull, "system-display-dimmed", nsnull); + break; + case MeeGo::QmDisplayState::Dimmed: + os->NotifyObservers(nsnull, "system-display-off", nsnull); + break; + default: + NS_WARNING("Unknown display state"); + break; + } +} + +void nsNativeAppSupportQt::deviceModeChanged(MeeGo::QmDeviceMode::DeviceMode mode) +{ + nsCOMPtr os = mozilla::services::GetObserverService(); + if (!os) + return; + + switch (mode) { + case MeeGo::QmDeviceMode::DeviceMode::Normal: + os->NotifyObservers(nsnull, "profile-change-net-restore", nsnull); + break; + case MeeGo::QmDeviceMode::DeviceMode::Flight: + os->NotifyObservers(nsnull, "profile-change-net-teardown", nsnull); + break; + case MeeGo::QmDeviceMode::DeviceMode::Error: + default: + NS_WARNING("Unknown DeviceMode"); + break; + } +} + +void nsNativeAppSupportQt::RefreshStates() +{ + activityChanged(mActivity.get()); + displayStateChanged(mDisplayState.get()); + deviceModeChanged(mDeviceMode.getMode()); +} #endif -}; NS_IMETHODIMP nsNativeAppSupportQt::Start(PRBool* aRetVal) { NS_ASSERTION(gAppData, "gAppData must not be null."); +#ifdef MOZ_ENABLE_QMSYSTEM2 + connect(&mActivity, SIGNAL(activityChanged(MeeGo::QmActivity::Activity)), this, SLOT(activityChanged(MeeGo::QmActivity::Activity))); + connect(&mDeviceMode, SIGNAL(deviceModeChanged(MeeGo::QmDeviceMode::DeviceMode)), this, SLOT(deviceModeChanged(MeeGo::QmDeviceMode::DeviceMode))); + connect(&mDisplayState, SIGNAL(displayStateChanged(MeeGo::QmDisplayState::DisplayState)), this, SLOT(displayStateChanged(MeeGo::QmDisplayState::DisplayState))); + // Init states withing next event loop iteration + QTimer::singleShot(0, this, SLOT(RefreshStates())); +#endif + *aRetVal = PR_TRUE; #ifdef MOZ_ENABLE_LIBCONIC g_type_init(); diff --git a/toolkit/xre/nsNativeAppSupportQt.h b/toolkit/xre/nsNativeAppSupportQt.h new file mode 100644 index 000000000000..98df760bb215 --- /dev/null +++ b/toolkit/xre/nsNativeAppSupportQt.h @@ -0,0 +1,79 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 et sw=2 tw=80: */ +/* ***** 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 Corporation code. + * + * The Initial Developer of the Original Code is Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2011 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Oleg Romashin + * + * 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 ***** */ + +#include +#ifdef MOZ_ENABLE_QMSYSTEM2 +#include "qmdevicemode.h" +#include "qmdisplaystate.h" +#include "qmactivity.h" +#endif +#include "nsNativeAppSupportBase.h" +#include "nsString.h" + +#ifdef MOZ_ENABLE_LIBCONIC +#include +#endif + +#if (MOZ_PLATFORM_MAEMO == 5) +#include +#endif + +class nsNativeAppSupportQt : public QObject, public nsNativeAppSupportBase +{ + Q_OBJECT +public: + NS_IMETHOD Start(PRBool* aRetVal); + NS_IMETHOD Stop(PRBool* aResult); +#if (MOZ_PLATFORM_MAEMO == 5) + // Osso context must be initialized for maemo5 otherwise we will be killed in ~20 seconds + osso_context_t *m_osso_context; +#endif +#ifdef MOZ_ENABLE_QMSYSTEM2 +public Q_SLOTS: + void activityChanged(MeeGo::QmActivity::Activity activity); + void deviceModeChanged(MeeGo::QmDeviceMode::DeviceMode mode); + void displayStateChanged(MeeGo::QmDisplayState::DisplayState state); + void RefreshStates(); + +private: + MeeGo::QmDeviceMode mDeviceMode; + MeeGo::QmDisplayState mDisplayState; + MeeGo::QmActivity mActivity; +#endif +}; + diff --git a/widget/src/qt/mozqwidget.h b/widget/src/qt/mozqwidget.h index 19de1f927b01..a2d52afe36ba 100644 --- a/widget/src/qt/mozqwidget.h +++ b/widget/src/qt/mozqwidget.h @@ -321,7 +321,7 @@ private: */ class MozMGraphicsView : public MWindow { - + Q_OBJECT public: MozMGraphicsView(MozQWidget* aTopLevel, QWidget* aParent = nsnull) : MWindow(aParent) @@ -330,6 +330,22 @@ public: { MozMSceneWindow* page = new MozMSceneWindow(aTopLevel); page->appear(this); + QObject::connect(this, SIGNAL(switcherEntered()), this, SLOT(onSwitcherEntered())); + QObject::connect(this, SIGNAL(switcherExited()), this, SLOT(onSwitcherExited())); + } + +public Q_SLOTS: + void onSwitcherEntered() { + nsCOMPtr os = mozilla::services::GetObserverService(); + if (!os) + return; + os->NotifyObservers(nsnull, "ts-background", nsnull); + } + void onSwitcherExited() { + nsCOMPtr os = mozilla::services::GetObserverService(); + if (!os) + return; + os->NotifyObservers(nsnull, "ts-foreground", nsnull); } protected: From 4c4fa57f0a7e25d77102a593d9c56bfa2242c8fc Mon Sep 17 00:00:00 2001 From: Oleg Romashin Date: Fri, 19 Aug 2011 13:09:26 +0200 Subject: [PATCH 09/71] Bug 679283 - Implement DeviceMotion deviceOrientation for Qt port r=dougt --- dom/system/unix/Makefile.in | 5 +- dom/system/unix/nsQTMDeviceMotionSystem.cpp | 126 ++++++++++++++++++++ dom/system/unix/nsQTMDeviceMotionSystem.h | 100 ++++++++++++++++ 3 files changed, 230 insertions(+), 1 deletion(-) create mode 100644 dom/system/unix/nsQTMDeviceMotionSystem.cpp create mode 100644 dom/system/unix/nsQTMDeviceMotionSystem.h diff --git a/dom/system/unix/Makefile.in b/dom/system/unix/Makefile.in index ca62e122f4f8..fa443281fea6 100644 --- a/dom/system/unix/Makefile.in +++ b/dom/system/unix/Makefile.in @@ -53,9 +53,11 @@ include $(topsrcdir)/config/config.mk include $(topsrcdir)/ipc/chromium/chromium-config.mk +ifndef MOZ_ENABLE_QTMOBILITY CPPSRCS = \ nsDeviceMotionSystem.cpp \ $(NULL) +endif ifdef MOZ_MAEMO_LIBLOCATION CPPSRCS += MaemoLocationProvider.cpp @@ -69,9 +71,10 @@ CPPSRCS += nsHapticFeedback.cpp LOCAL_INCLUDES += $(MOZ_DBUS_CFLAGS) \ $(NULL) ifdef MOZ_ENABLE_QTMOBILITY -MOCSRCS += moc_QTMLocationProvider.cpp +MOCSRCS += moc_QTMLocationProvider.cpp moc_nsQTMDeviceMotionSystem.cpp CPPSRCS += $(MOCSRCS) \ QTMLocationProvider.cpp \ + nsQTMDeviceMotionSystem.cpp \ $(NULL) LOCAL_INCLUDES += $(MOZ_QT_CFLAGS) \ -I$(topsrcdir)/dom/src/geolocation \ diff --git a/dom/system/unix/nsQTMDeviceMotionSystem.cpp b/dom/system/unix/nsQTMDeviceMotionSystem.cpp new file mode 100644 index 000000000000..8a9909bd7cb8 --- /dev/null +++ b/dom/system/unix/nsQTMDeviceMotionSystem.cpp @@ -0,0 +1,126 @@ +/* -*- Mode: c++; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- + * ***** 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 Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2011 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Oleg Romashin + * + * 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 ***** */ + +#include "mozilla/dom/ContentChild.h" +#include "nsQTMDeviceMotionSystem.h" +#include +#include +#include + +#include "nsXULAppAPI.h" + +using namespace mozilla; +using namespace QtMobility; + +bool +MozQAccelerometerSensorFilter::filter(QAccelerometerReading* reading) +{ + mSystem.DeviceMotionChanged(nsIDeviceMotionData::TYPE_ACCELERATION, + -reading->x(), + -reading->y(), + -reading->z()); + return true; +} + +bool +MozQRotationSensorFilter::filter(QRotationReading* reading) +{ + // QRotationReading class: + // - the rotation around z axis (alpha) is given as z in QRotationReading; + // - the rotation around x axis (beta) is given as x in QRotationReading; + // - the rotation around y axis (gamma) is given as y in QRotationReading; + // See: http://doc.qt.nokia.com/qtmobility-1.0/qrotationreading.html + mSystem.DeviceMotionChanged(nsIDeviceMotionData::TYPE_ORIENTATION, + reading->z(), + reading->x(), + reading->y()); + return true; +} + +nsDeviceMotionSystem::nsDeviceMotionSystem() +{ + if (XRE_GetProcessType() == GeckoProcessType_Default) { + mAccelerometer = new QAccelerometer(); + mAccelerometerFilter = new MozQAccelerometerSensorFilter(*this); + mAccelerometer->addFilter(mAccelerometerFilter); + mRotation = new QRotationSensor(); + mRotationFilter = new MozQRotationSensorFilter(*this); + mRotation->addFilter(mRotationFilter); + } +} + +nsDeviceMotionSystem::~nsDeviceMotionSystem() +{ + if (XRE_GetProcessType() == GeckoProcessType_Default) { + mAccelerometer->removeFilter(mAccelerometerFilter); + mAccelerometer->stop(); + mRotation->removeFilter(mRotationFilter); + mRotation->stop(); + delete mAccelerometer; + delete mAccelerometerFilter; + delete mRotation; + delete mRotationFilter; + } +} + +void nsDeviceMotionSystem::Startup() +{ + if (XRE_GetProcessType() == GeckoProcessType_Default) { + mAccelerometer->start(); + if (!mAccelerometer->isActive()) { + NS_WARNING("AccelerometerSensor didn't start!"); + } + mRotation->start(); + if (!mRotation->isActive()) { + NS_WARNING("RotationSensor didn't start!"); + } + } + else + mozilla::dom::ContentChild::GetSingleton()-> + SendAddDeviceMotionListener(); +} + +void nsDeviceMotionSystem::Shutdown() +{ + if (XRE_GetProcessType() == GeckoProcessType_Default) { + mAccelerometer->stop(); + mRotation->stop(); + } + else + mozilla::dom::ContentChild::GetSingleton()-> + SendRemoveDeviceMotionListener(); +} diff --git a/dom/system/unix/nsQTMDeviceMotionSystem.h b/dom/system/unix/nsQTMDeviceMotionSystem.h new file mode 100644 index 000000000000..5df59c56dcbd --- /dev/null +++ b/dom/system/unix/nsQTMDeviceMotionSystem.h @@ -0,0 +1,100 @@ +/* ***** 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 Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2011 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Oleg Romashin + * + * 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 ***** */ + +#ifndef nsDeviceMotionSystem_h +#define nsDeviceMotionSystem_h + +#include +#include +#include +#include "nsDeviceMotion.h" + +using namespace QtMobility; + + +class MozQAccelerometerSensorFilter; +class MozQRotationSensorFilter; + +class nsDeviceMotionSystem : public nsDeviceMotion +{ +public: + nsDeviceMotionSystem(); + virtual ~nsDeviceMotionSystem(); + +private: + virtual void Startup(); + virtual void Shutdown(); + + QtMobility::QAccelerometer* mAccelerometer; + MozQAccelerometerSensorFilter* mAccelerometerFilter; + QtMobility::QRotationSensor* mRotation; + MozQRotationSensorFilter* mRotationFilter; +}; + +class MozQAccelerometerSensorFilter : public QObject, public QAccelerometerFilter +{ + Q_OBJECT + +public: + MozQAccelerometerSensorFilter(nsDeviceMotionSystem& aSystem) : mSystem(aSystem) {} + + virtual ~MozQAccelerometerSensorFilter(){} + + virtual bool filter(QAccelerometerReading* reading); + +private: + bool filter(QSensorReading *reading) { return filter(static_cast(reading)); } + nsDeviceMotionSystem& mSystem; +}; + +class MozQRotationSensorFilter : public QObject, public QRotationFilter +{ + Q_OBJECT + +public: + MozQRotationSensorFilter(nsDeviceMotionSystem& aSystem) : mSystem(aSystem) {} + + virtual ~MozQRotationSensorFilter(){} + + virtual bool filter(QRotationReading* reading); + +private: + bool filter(QSensorReading *reading) { return filter(static_cast(reading)); } + nsDeviceMotionSystem& mSystem; +}; + +#endif /* nsDeviceMotionSystem_h */ + From a7f96cc6eca4c59df79efb2ebc602e56a34b64a4 Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Fri, 19 Aug 2011 13:20:51 +0200 Subject: [PATCH 10/71] Backout bug 679733 for Qt bustage. --- toolkit/xre/Makefile.in | 3 - toolkit/xre/nsNativeAppSupportQt.cpp | 97 ++++++---------------------- toolkit/xre/nsNativeAppSupportQt.h | 79 ---------------------- widget/src/qt/mozqwidget.h | 18 +----- 4 files changed, 20 insertions(+), 177 deletions(-) delete mode 100644 toolkit/xre/nsNativeAppSupportQt.h diff --git a/toolkit/xre/Makefile.in b/toolkit/xre/Makefile.in index 9c1e49fdaa6c..0082e448eb47 100644 --- a/toolkit/xre/Makefile.in +++ b/toolkit/xre/Makefile.in @@ -102,9 +102,6 @@ ifeq ($(MOZ_WIDGET_TOOLKIT),gtk2) CPPSRCS += nsNativeAppSupportUnix.cpp else ifeq ($(MOZ_WIDGET_TOOLKIT),qt) -MOCSRCS += moc_nsNativeAppSupportQt.cpp - $(NULL) -CPPSRCS += $(MOCSRCS) CPPSRCS += nsNativeAppSupportQt.cpp CPPSRCS += nsQAppInstance.cpp EXPORTS += nsQAppInstance.h diff --git a/toolkit/xre/nsNativeAppSupportQt.cpp b/toolkit/xre/nsNativeAppSupportQt.cpp index 4e2ff58a299b..fe9b9075c17f 100644 --- a/toolkit/xre/nsNativeAppSupportQt.cpp +++ b/toolkit/xre/nsNativeAppSupportQt.cpp @@ -37,92 +37,33 @@ * ***** END LICENSE BLOCK ***** */ #include -#include "mozilla/ipc/GeckoChildProcessHost.h" -#include "nsNativeAppSupportQt.h" -#include "nsCOMPtr.h" -#include "nsIObserverService.h" -#include "mozilla/Services.h" -#include +#include "nsNativeAppSupportBase.h" +#include "nsString.h" -#ifdef MOZ_ENABLE_QMSYSTEM2 -void -nsNativeAppSupportQt::activityChanged(MeeGo::QmActivity::Activity activity) -{ - nsCOMPtr os = mozilla::services::GetObserverService(); - if (!os) - return; - - if (MeeGo::QmActivity::Inactive == activity) { - os->NotifyObservers(nsnull, "system-idle", nsnull); - } else { - os->NotifyObservers(nsnull, "system-active", nsnull); - } -} - -void -nsNativeAppSupportQt::displayStateChanged(MeeGo::QmDisplayState::DisplayState state) -{ - nsCOMPtr os = mozilla::services::GetObserverService(); - if (!os) - return; - - switch (state) { - case MeeGo::QmDisplayState::On: - os->NotifyObservers(nsnull, "system-display-on", nsnull); - break; - case MeeGo::QmDisplayState::Off: - os->NotifyObservers(nsnull, "system-display-dimmed", nsnull); - break; - case MeeGo::QmDisplayState::Dimmed: - os->NotifyObservers(nsnull, "system-display-off", nsnull); - break; - default: - NS_WARNING("Unknown display state"); - break; - } -} - -void nsNativeAppSupportQt::deviceModeChanged(MeeGo::QmDeviceMode::DeviceMode mode) -{ - nsCOMPtr os = mozilla::services::GetObserverService(); - if (!os) - return; - - switch (mode) { - case MeeGo::QmDeviceMode::DeviceMode::Normal: - os->NotifyObservers(nsnull, "profile-change-net-restore", nsnull); - break; - case MeeGo::QmDeviceMode::DeviceMode::Flight: - os->NotifyObservers(nsnull, "profile-change-net-teardown", nsnull); - break; - case MeeGo::QmDeviceMode::DeviceMode::Error: - default: - NS_WARNING("Unknown DeviceMode"); - break; - } -} - -void nsNativeAppSupportQt::RefreshStates() -{ - activityChanged(mActivity.get()); - displayStateChanged(mDisplayState.get()); - deviceModeChanged(mDeviceMode.getMode()); -} +#ifdef MOZ_ENABLE_LIBCONIC +#include #endif +#if (MOZ_PLATFORM_MAEMO == 5) +#include +#endif + +class nsNativeAppSupportQt : public nsNativeAppSupportBase +{ +public: + NS_IMETHOD Start(PRBool* aRetVal); + NS_IMETHOD Stop(PRBool* aResult); +#if (MOZ_PLATFORM_MAEMO == 5) + // Osso context must be initialized for maemo5 otherwise we will be killed in ~20 seconds + osso_context_t *m_osso_context; +#endif +}; + NS_IMETHODIMP nsNativeAppSupportQt::Start(PRBool* aRetVal) { NS_ASSERTION(gAppData, "gAppData must not be null."); -#ifdef MOZ_ENABLE_QMSYSTEM2 - connect(&mActivity, SIGNAL(activityChanged(MeeGo::QmActivity::Activity)), this, SLOT(activityChanged(MeeGo::QmActivity::Activity))); - connect(&mDeviceMode, SIGNAL(deviceModeChanged(MeeGo::QmDeviceMode::DeviceMode)), this, SLOT(deviceModeChanged(MeeGo::QmDeviceMode::DeviceMode))); - connect(&mDisplayState, SIGNAL(displayStateChanged(MeeGo::QmDisplayState::DisplayState)), this, SLOT(displayStateChanged(MeeGo::QmDisplayState::DisplayState))); - // Init states withing next event loop iteration - QTimer::singleShot(0, this, SLOT(RefreshStates())); -#endif - *aRetVal = PR_TRUE; #ifdef MOZ_ENABLE_LIBCONIC g_type_init(); diff --git a/toolkit/xre/nsNativeAppSupportQt.h b/toolkit/xre/nsNativeAppSupportQt.h deleted file mode 100644 index 98df760bb215..000000000000 --- a/toolkit/xre/nsNativeAppSupportQt.h +++ /dev/null @@ -1,79 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 et sw=2 tw=80: */ -/* ***** 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 Corporation code. - * - * The Initial Developer of the Original Code is Mozilla Foundation. - * Portions created by the Initial Developer are Copyright (C) 2011 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Oleg Romashin - * - * 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 ***** */ - -#include -#ifdef MOZ_ENABLE_QMSYSTEM2 -#include "qmdevicemode.h" -#include "qmdisplaystate.h" -#include "qmactivity.h" -#endif -#include "nsNativeAppSupportBase.h" -#include "nsString.h" - -#ifdef MOZ_ENABLE_LIBCONIC -#include -#endif - -#if (MOZ_PLATFORM_MAEMO == 5) -#include -#endif - -class nsNativeAppSupportQt : public QObject, public nsNativeAppSupportBase -{ - Q_OBJECT -public: - NS_IMETHOD Start(PRBool* aRetVal); - NS_IMETHOD Stop(PRBool* aResult); -#if (MOZ_PLATFORM_MAEMO == 5) - // Osso context must be initialized for maemo5 otherwise we will be killed in ~20 seconds - osso_context_t *m_osso_context; -#endif -#ifdef MOZ_ENABLE_QMSYSTEM2 -public Q_SLOTS: - void activityChanged(MeeGo::QmActivity::Activity activity); - void deviceModeChanged(MeeGo::QmDeviceMode::DeviceMode mode); - void displayStateChanged(MeeGo::QmDisplayState::DisplayState state); - void RefreshStates(); - -private: - MeeGo::QmDeviceMode mDeviceMode; - MeeGo::QmDisplayState mDisplayState; - MeeGo::QmActivity mActivity; -#endif -}; - diff --git a/widget/src/qt/mozqwidget.h b/widget/src/qt/mozqwidget.h index a2d52afe36ba..19de1f927b01 100644 --- a/widget/src/qt/mozqwidget.h +++ b/widget/src/qt/mozqwidget.h @@ -321,7 +321,7 @@ private: */ class MozMGraphicsView : public MWindow { - Q_OBJECT + public: MozMGraphicsView(MozQWidget* aTopLevel, QWidget* aParent = nsnull) : MWindow(aParent) @@ -330,22 +330,6 @@ public: { MozMSceneWindow* page = new MozMSceneWindow(aTopLevel); page->appear(this); - QObject::connect(this, SIGNAL(switcherEntered()), this, SLOT(onSwitcherEntered())); - QObject::connect(this, SIGNAL(switcherExited()), this, SLOT(onSwitcherExited())); - } - -public Q_SLOTS: - void onSwitcherEntered() { - nsCOMPtr os = mozilla::services::GetObserverService(); - if (!os) - return; - os->NotifyObservers(nsnull, "ts-background", nsnull); - } - void onSwitcherExited() { - nsCOMPtr os = mozilla::services::GetObserverService(); - if (!os) - return; - os->NotifyObservers(nsnull, "ts-foreground", nsnull); } protected: From d2242323484098d997bd01aee8d7a6eb1c79255d Mon Sep 17 00:00:00 2001 From: Marco Bonardo Date: Fri, 19 Aug 2011 15:01:21 +0200 Subject: [PATCH 11/71] Bug 669905 - Searching in Downloads folder should limit the search to downloads. r=dietrich --- browser/components/places/content/places.js | 74 ++++++-- browser/components/places/content/places.xul | 12 +- .../tests/browser/browser_library_search.js | 169 ++++++++++-------- .../chrome/browser/places/places.properties | 1 + 4 files changed, 163 insertions(+), 93 deletions(-) diff --git a/browser/components/places/content/places.js b/browser/components/places/content/places.js index 51e3f5d666bb..d47ea60d1755 100644 --- a/browser/components/places/content/places.js +++ b/browser/components/places/content/places.js @@ -277,17 +277,30 @@ var PlacesOrganizer = { * the node to set up scope from */ _setSearchScopeForNode: function PO__setScopeForNode(aNode) { - var itemId = aNode.itemId; + let itemId = aNode.itemId; + + // Set default buttons status. + let bookmarksButton = document.getElementById("scopeBarAll"); + bookmarksButton.hidden = false; + let downloadsButton = document.getElementById("scopeBarDownloads"); + downloadsButton.hidden = true; + if (PlacesUtils.nodeIsHistoryContainer(aNode) || itemId == PlacesUIUtils.leftPaneQueries["History"]) { PlacesQueryBuilder.setScope("history"); } - // Default to All Bookmarks for all other nodes, per bug 469437. - else + else if (itemId == PlacesUIUtils.leftPaneQueries["Downloads"]) { + downloadsButton.hidden = false; + bookmarksButton.hidden = true; + PlacesQueryBuilder.setScope("downloads"); + } + else { + // Default to All Bookmarks for all other nodes, per bug 469437. PlacesQueryBuilder.setScope("bookmarks"); + } // Enable or disable the folder scope button. - var folderButton = document.getElementById("scopeBarFolder"); + let folderButton = document.getElementById("scopeBarFolder"); folderButton.hidden = !PlacesUtils.nodeIsFolder(aNode) || itemId == PlacesUIUtils.allBookmarksFolderId; }, @@ -901,9 +914,21 @@ var PlacesSearchBox = { options.queryType = Ci.nsINavHistoryQueryOptions.QUERY_TYPE_HISTORY; content.load([query], options); } - else + else { content.applyFilter(filterString); + } break; + case "downloads": { + let query = PlacesUtils.history.getNewQuery(); + query.searchTerms = filterString; + query.setTransitions([Ci.nsINavHistoryService.TRANSITION_DOWNLOAD], 1); + let options = currentOptions.clone(); + // Make sure we're getting uri results. + options.resultType = currentOptions.RESULT_TYPE_URI; + options.queryType = Ci.nsINavHistoryQueryOptions.QUERY_TYPE_HISTORY; + content.load([query], options); + break; + } default: throw "Invalid filterCollection on search"; break; @@ -933,17 +958,28 @@ var PlacesSearchBox = { /** * Updates the display with the title of the current collection. - * @param title + * @param aTitle * The title of the current collection. */ - updateCollectionTitle: function PSB_updateCollectionTitle(title) { - if (title) - this.searchFilter.placeholder = - PlacesUIUtils.getFormattedString("searchCurrentDefault", [title]); - else - this.searchFilter.placeholder = this.filterCollection == "history" ? - PlacesUIUtils.getString("searchHistory") : - PlacesUIUtils.getString("searchBookmarks"); + updateCollectionTitle: function PSB_updateCollectionTitle(aTitle) { + let title = ""; + if (aTitle) { + title = PlacesUIUtils.getFormattedString("searchCurrentDefault", + [aTitle]); + } + else { + switch(this.filterCollection) { + case "history": + title = PlacesUIUtils.getString("searchHistory"); + break; + case "downloads": + title = PlacesUIUtils.getString("searchDownloads"); + break; + default: + title = PlacesUIUtils.getString("searchBookmarks"); + } + } + this.searchFilter.placeholder = title; }, /** @@ -1025,6 +1061,9 @@ var PlacesQueryBuilder = { case "scopeBarFolder": this.setScope("collection"); break; + case "scopeBarDownloads": + this.setScope("downloads"); + break; case "scopeBarAll": this.setScope("bookmarks"); break; @@ -1040,7 +1079,8 @@ var PlacesQueryBuilder = { * PSB_search()). If there is an active search, it's performed again to * update the content tree. * @param aScope - * the search scope, "bookmarks", "collection", or "history" + * The search scope: "bookmarks", "collection", "downloads" or + * "history". */ setScope: function PQB_setScope(aScope) { // Determine filterCollection, folders, and scopeButtonId based on aScope. @@ -1072,6 +1112,10 @@ var PlacesQueryBuilder = { PlacesUtils.toolbarFolderId, PlacesUtils.unfiledBookmarksFolderId); break; + case "downloads": + filterCollection = "downloads"; + scopeButtonId = "scopeBarDownloads"; + break; default: throw "Invalid search scope"; break; diff --git a/browser/components/places/content/places.xul b/browser/components/places/content/places.xul index 63c4517213a7..a355037fb795 100644 --- a/browser/components/places/content/places.xul +++ b/browser/components/places/content/places.xul @@ -412,18 +412,16 @@ oncommand="PlacesQueryBuilder.onScopeSelected(this);" label="&search.scopeBookmarks.label;" accesskey="&search.scopeBookmarks.accesskey;"/> - +