blit() calls draw_scaled_bitmap() behind the scenes in scaled contexts,
and that doesn't like src_rect to be outside of the source bitmap's
bounds. Implicitly clip with the source rect, like the non-scaled
codepath already does.
Fixes#5017 even more.
Consider
draw_scaled_bitmap({0, 0, 10, 10}, source, {0, 0, 5, 5}).
Imagine wanting to split that up into two calls, like e.g. the
compositor when redrawing the background with damage rects. You really
want to be able to say
draw_scaled_bitmap({0, 0, 5, 10}, source, {0, 0, 2.5, 5})
but up to now you couldn't. Now you can.
This makes painting very low-res images (such as tile.png) in mode
"stretch" work much better.
A C++ source file containing just
#include <LibFoo/Bar.h>
should always compile cleanly.
This patch adds missing header inclusions that could have caused weird error
messages if they were used in a different context. Also, this confused QtCreator.
Application.h includes Widget.h which includes Application.h. I'm not entirely
sure what the semantics are in this case, but avoiding this seems to be the
safer approach. In this case, Widget does not actually use Application, so let's
just remove the unused include.
With this patch it is possible to create PNG files. Only minimal options
are supported. The PNG is created with one big IDAT chunk containing
only non-compressible DEFLATE blocks.
This allows us to implement mkstemp() with open() directly, instead of
first lstat()'ing, and then open()'ing the filename.
Also implement tmpfile() in terms of mkstemp() instead of mktemp().
It's less code, and blit() already handles scaled painters.
Fixes the window server asserting in highdpi mode with a centered
background image. Part of #5017.
draw_scaled_bitmap() has a clearer API (just source and dest rects --
blit_scaled() took those and scale factors and then ignored width and
height on the source rect and it was less clear what it was supposed to
do), and they do mostly the same thing.
The draw_scaled_bitmap() API takes an IntRect as source rect, so it's
currently not always possible to split a big draw_scaled_bitmap() into
two (or more) smaller draw_scaled_bitmap() calls that do the same thing
-- that'd require FloatRects. The compositor kind of wants this to be
possible, but there's already a FIXME about this not looking quite right
with the previous approach either.
draw_scaled_bitmap() handles transparent sources, so after this change
wallpapers with transparency will be blended instead of copied. But that
seems fine, and if not, the Right Fix for that is to remove the alpha
channel from wallpapers after loading them anyways.
As an added bonus, draw_scaled_bitmap() already handles display scale,
so this fixes window server asserts for background images that are shown
as "stretch" (#5017). The window server still asserts for "tile" and
"offset" for now though.
Calling draw_scaled_bitmap() here exposed a bug in it fixed by #5041.
Before that is merged, this change here will cause smearing on the
background image when moving windows around.
If a user is missing from /etc/shadow, we used to just allow anyone to
authenticate as that user without a password.
With this patch, authentication will instead always fail.
Now that we've moved to atomic replacement of these files when altering
them, we don't need to keep them open for the lifetime of Core::Account
so just simplify this and close them when they are not needed.
Before this patch, we had a nasty race condition when changing a user's
password: there was a time window between truncating /etc/shadow and
writing out its new contents, where you could simply "su" to root
without using a password.
Instead of writing directly to /etc/passwd and /etc/shadow, we now
create temporary files in /etc and fill them with the new contents.
Those files are then atomically renamed to /etc/passwd and /etc/shadow.
Sadly, fixing this race requires giving the passwd program a lot more
privileges. This is something we can and should improve upon. :^)
Apparently memfd_create() is newish in glibc, and oss-fuzz
uses Ubuntu 16.04 as base for its docker images, which doens't
yet have memfd_create(). But, not to worry, it does have the syscall
define and that's all we really need :/
..and allow implicit creation of KResult and KResultOr from ErrnoCode.
This means that kernel functions that return those types can finally
do "return EINVAL;" and it will just work.
There's a handful of functions that still deal with signed integers
that should be converted to return KResults.
Moves Painter away from general affine transport support a bit, but
this scale factor business does feel like it's a bit different.
This is conceptually cleaner (everything should use logical coordinates
as much as possible), and it means the code in GUI::Painter() will work
without changes due to that, but the draw function implementations
overall get a bit murkier (draw_rect() becomes nicer though). Still,
feels like the right direction.
No behavior change.
Similar to LibC storing an assertion message before aborting, process
death by pledge violation now sets a "pledge_violation" key with the
respective pledge name as value in its coredump metadata, which the
CrashReporter will then show.
Without this, the oss-fuzz build says:
../Userland/Libraries/LibJS/AST.cpp:58:34: error: member access into incomplete type 'const std::type_info'
return demangle(typeid(*this).name()).substring(4);
^
Bitmap::load_from_file("foo.png", 2) will now look for "foo-2x.png" and
try load that as a bitmap with scale factor 2 if it exists. If it
doesn't, it falls back to the 1x bitmap as normal.
Only places that know that they'll draw the bitmap to a 2x painter
should pass "2" for the second argument.
Use this new API in WindowServer for loading window buttons and
cursors.
As a testing aid, ctrl-shift-super-i can force HighDPI icons off in
HighDPI mode. Toggling between low-res and high-res icons makes it easy
to see if the high-res version of an icon looks right: It should look
like the low-res version, just less jaggy.
We'll likely have to grow a better API for loading scaled resources, but
for now this suffices.
Things to check:
- `chres 640 480` followed by `chres 640 480 2` followed by
`chres 640 480`
- window buttons in window context menu (in task bar and on title bar)
still have low-res icons
- ctrl-shift-super-i in high-res mode toggles sharpness of window
buttons and of arrow cursorf
- arrow cursor hotspot is still where you'd expect
Gfx::Bitmap can now store its scale factor. Normally it's 1, but
in high dpi mode it can be 2.
If a Bitmap with a scale factor of 2 is blitted to a Painter with
scale factor of 2, the pixels can be copied over without any resampling.
(When blitting a Bitmap with a scale factor of 1 to a Painter with scale
factor of 2, the Bitmap is painted at twice its width and height at
paint time. Blitting a Bitmap with a scale factor of 2 to a Painter with
scale factor 1 is not supported.)
A Bitmap with scale factor of 2 reports the same width() and height() as
one with scale factor 1. That's important because many places in the
codebase use a bitmap's width() and height() to layout Widgets, and all
widget coordinates are in logical coordinates as well, per
Documentation/HighDPI.md.
Bitmap grows physical_width() / physical_height() to access the actual
pixel size. Update a few callers that work with pixels to call this
instead.
Make Painter's constructor take its scale factor from the target bitmap
that's passed in, and update its various blit() methods to handle
blitting a 2x bitmap to a 2x painter. This allows removing some gnarly
code in Compositor. (In return, put some new gnarly code in
LibGfxScaleDemo to preserve behavior there.)
No intended behavior change.
Quoting POSIX:
https://pubs.opengroup.org/onlinepubs/009695399/functions/tzset.html
The tzset() function also shall set the external variable daylight
to 0 if Daylight Savings Time conversions should never be applied
for the timezone in use; otherwise, non-zero.
We're already pretending to be in UTC+0 and setting timezone to 0
accordingly, we can also fake the absence of Daylight Savings Time.
Since tzset() itself pretends to succeed (it just sets timezone = 0 for
now), it seems unwise to leave tzname uninitialized. Since Serenity
already assumes UTC pretty much everywhere time is used, let's continue
that trend here. Quoting POSIX:
https://pubs.opengroup.org/onlinepubs/009695399/functions/tzset.html
The tzset() function shall use the value of the environment variable
TZ to set time conversion information used by ctime(), localtime(),
mktime(), and strftime(). If TZ is absent from the environment,
implementation-defined default timezone information shall be used.
So we still don't care about TZ at all, but the program doesn't need to
know! :^)
This matches what musl libc ("UTC") and glibc ("GMT") do, see:
- https://sourceware.org/git/?p=glibc.git;a=blob;f=time/tzset.c
- https://git.musl-libc.org/cgit/musl/tree/src/time/__tz.c
The FFC now supports both vertical and horizontal flex layout, based on
the flex-direction property. It's still extremely naive, but at least
now you can be naive in two directions! :^)
This implementation of flexbox is going to take a lot of work, but at
least now we've gotten started.
Just have all the timing functions return 0 for now.
We can now run the Shynet JS on https://linus.dev/ although the XHR
is rejected by our same-origin policy.
Since Web::Bindings::WindowObject inherits from JS::GlobalObject, it
cannot also inherit from Web::Bindings::EventTargetWrapper.
However, that's not actually necessary. Instead, we simply set the
Window object's prototype to the EventTargetPrototype, and add a little
extra branch in the impl_from() function that turns the JS "this" value
into a DOM::EventTarget*.
With this, you can now call window.addEventListener()! Very cool :^)
Fixes#4758.
Instead of each IDL interface wrapper having its own set of all the
attributes and functions, they are moved to the prototype. This matches
what we already do in LibJS.
Also, this should be spec compliant with the web as well, though there
may be *some* content out there that expects some things to be directly
on the wrapper since that's how things used to work in major browsers
a long time ago. But let's just not worry about that for now.
More work towards #4789
We now instantiate all the generated web API constructors and expose
them on the window object. We also set the generated prototypes on
instantiated wrappers.
Also, we should obviously find a way to generate this code. :^)
This patch adds a FooPrototype and FooConstructor class for each IDL
interface we generate JS bindings for.
These classes are very primitive and don't do everything they should
yet, but we have to start somewhere. :^)
Work towards #4789
This adds support for FUTEX_WAKE_OP, FUTEX_WAIT_BITSET, FUTEX_WAKE_BITSET,
FUTEX_REQUEUE, and FUTEX_CMP_REQUEUE, as well well as global and private
futex and absolute/relative timeouts against the appropriate clock. This
also changes the implementation so that kernel resources are only used when
a thread is blocked on a futex.
Global futexes are implemented as offsets in VMObjects, so that different
processes can share a futex against the same VMObject despite potentially
being mapped at different virtual addresses.
The generic is<T>() uses dynamic_cast which is fine in the majority
of cases, but when one of them shows up in profiles, we can make it
faster by answering the is-a question manually.
All users of this mechanism have been switched to anonymous files and
passing file descriptors with sendfd()/recvfd().
Shbufs got us where we are today, but it's time we say good-bye to them
and welcome a much more idiomatic replacement. :^)
decode_png_chunks() is not handling "critical" chunks, unlike
decode_png_size() for example. When we encounter a chunk decoding
failure, e.g. because not enough bytes were left to read, just continue
with decoding the bitmap - which will fail on its own, if we're missing
some required chunk(s).
Fixes#4984.
To support this, the GUI process and the WebContent service will now
coordinate their backing store bitmaps. Each backing store can be
referred to by a serial ID, and we don't need to keep resending it
as a file descriptor.
We should probably do something similar in WindowServer. :^)
The realpath syscall can attempt to return arbitrarily long paths, in particular
paths that are longer than PATH_MAX. The only way to detect this case is
checking whether 'rc', the true length of the returned path including NUL byte,
exceeds our buffer length. In such a case, the buffer contains invalid data.
All Serenity code calls LibC's realpath() with a nullptr buffer, meaning that
realpath is supposed to allocate memory on its own. All Serenity code can handle
arbitrarily long paths returned by LibC's realpath, so it is safe to "do the
dance" and repeat the syscall with a new buffer.
Ports are likely to be graceful in this regard, too. If a Port calls realpath()
with a pre-allocated buffer, however, there is nothing better we can do than
return a truncated buffer.
The priority boosting mechanism has been broken for a very long time.
Let's remove it from the codebase and we can bring it back the day
someone feels like implementing it in a working way. :^)
64 was cutting it pretty close, especially now as we start using file
descriptor passing more and more.
This (1024) matches many other systems, and if we need more there's
always sys$poll().
IPC::File should only be used when there's an actual file to pass.
Invalid ShareableBitmaps don't have a backing file, so fix this by
first encoding a "valid" flag.
Adds a mechanism through which windowing clients can re-request an
UpdateSystemTheme message. This is currently used in SystemMenu's
ShutdownDialog to refresh it's theme when the dialog is instantiated.
This is in preparation of adding (much) more process information to
coredumps. As we can only have one null-terminated char[] of arbitrary
length in each struct it's now a single JSON blob, which is a great fit:
easily extensible in the future and allows for key/value pairs and even
nested objects, which will be used e.g. for the process environment, for
example.
Window icons in Taskbar were previously received in WM events with
shbuf ID's. Now that Gfx::ShareableBitmap is backed by anonymous files,
we can easily switch to using those.
Needed for the window server minimize animation.
draw_rect() can't just call draw_line() because that isn't
draw_op()-aware. The draw_op()-awareness in Painter looks a bit ad-hoc,
but that's for another day.
This patch replaces the use of shbufs for GUI::Window backing stores
with the new anonymous files mechanism.
Backing bitmaps are now built on memory allocated with anon_create().
They are passed across the IPC socket as IPC::File. This means that
WindowServer now pledges "recvfd" and graphical clients need to pledge
"sendfd" to work.
To support the cached bitmap swapping optimization on the WindowServer
side, each backing store is assigned an incrementing serial number on
the client side. (This allows us to re-use an already mapped file.)
This patch adds a new AnonymousFile class which is a File backed by
an AnonymousVMObject that can only be mmap'ed and nothing else, really.
I'm hoping that this can become a replacement for shbufs. :^)
Instead of storing the back/front buffers of a GUI::Window as just
Gfx::Bitmap, wrap them in a WindowBackingStore class.
This will allow us to add more information alongside the bitmaps while
keeping the back/front swapping logic simple.
This broke when switching IPC messages to support move-only types.
This pattern is not ideal, but the real fix for this will be using fd
passing instead of shbufs.
Fixes#4955.
If you don't need a file descriptor after sending it to someone over
IPC, construct it with IPC::File(fd, IPC::File::CloseAfterSending)
and LibIPC will take care of it for you. :^)
When receiving a file descriptor over IPC, the receiver must now call
take_fd() on the IPC::File to take over the descriptor. Otherwise,
IPC::File will close the file on destruction.
SOCK_NONBLOCK is a linux-ism that serenity and linux support. For lagom
builds, we use ioctl/fcntl to get a non-blocking socket the old
fashioned way. Some file re-org unhid the fcntl.h dependency of TcpServer,
so add the header explicitly.
This API was a mostly gratuitous deviation from POSIX that gave up some
portability in exchange for avoiding the occasional strlen().
I don't think that was actually achieving anything valuable, so let's
just chill out and have the same open() API as everyone else. :^)
This adds a scale factor to Painter, which will be used for HighDPI
support. It's also a step towards general affine transforms on Painters.
All of Painter's public API takes logical coordinates, while some
internals deal with physical coordinates now. If scale == 1, logical
and physical coordinates are the same. For scale == 2, a 200x100 bitmap
would be covered by a logical {0, 0, 100, 50} rect, while its physical
size would be {0, 0, 200, 100}.
Most of Painter's functions just assert that scale() == 1 is for now,
but most functions called by WindowServer are updated to handle
arbitrary (integer) scale.
Also add a new Demo "LibGfxScaleDemo" that covers the converted
functions and that can be used to iteratively add scaling support
to more functions.
To make Painter's interface deal with logical coordinates only,
make translation() and clip_rect() non-public.
The underlying fill_rect() works correctly, but the special case for
thickness = 1 was not blending the new color with the target pixel's
color, causing RGBA colors to be painted as their RGB counterpart.