diff options
2 files changed, 232 insertions, 0 deletions
diff --git a/CoreStructures b/CoreStructures
new file mode 100644
index 0000000..df540db
--- /dev/null
+++ b/CoreStructures
@@ -0,0 +1,130 @@
+Beryl's core structures - version this-is-not-complete-yet
+1. Scope of this document
+2. CompDisplay vs CompScreen
+3. CompDisplay
+4. CompScreen
+5. CompWindow
+6. Regions
+1. Scope of this document
+With this document I will attempt to clear up some confusions about the most
+important data structures in Beryl. I will not describ every part of the
+structures, but rather clear up some trickier parts.
+A good way to get to know these structures is to use the debug plugin. It
+allows you to easily view the CompScreen and CompWindow structure(s) with
+some of the sub-structures.
+2. CompDisplay vs CompScreen
+If you've seen the DISPLAY variable, it'll look something like this for most
+people: DISPLAY=:0.0 . The forst 0 here is the display, and the second 0
+is the screen. Each X server has ONE display, but can have multiple screen's.
+Do not confuse a screen with a monitor, though. In a xinerama-hinted
+enviroment (the most common multihead setup), the X server presents just one
+screen to the programs, but gives us hints about where the head/monitor
+stops and starts.
+Usually, there isn't any real work needed in a plugin to support multiscreen.
+All you need to do is make sure you deal with CompScreen and never assume
+that you can get the right CompScreen from display->screens. There are
+functions in core that lets you find a screen based on the root window. Use
+these, even if display->screens is very tempting.
+Generally, we keep bindings in Display-scope. This can add some complications,
+but make sure you find the right screen if you want your binding to only
+affect one screen. Take a look at rotate.c to see how this is done as an
+3. CompDisplay
+CompDisplay is mostly dealt with by core. It is the DataStructure that glues
+all the possible screens together. Chances are, you will mostly just work with
+d->activeWindow which defines the currently active (focused) window, and the
+d->pointerX/Y which tells you where the pointer is. Also, it stores the atoms
+fetched by core.
+4. CompScreen
+CompScreen is _the_ structure. You will get to know this wether you want to
+or not if you intend to do development on Beryl.
+First of all, it is a linked list item, so it contains a link to the next
+CompScreen. It also has a link to the CompDisplay structure it belongs to.
+Because of that fact, you never need to pass both CompDisplay and
+CompScreen to a function, and you are better off passing CompScreen than
+CompDisplay, because the latter can have several CompScreen's.
+Each screen has a uniqe root window, which is often used in identifying the
+screenw hen you get events. This is process is usually handled by core when
+you call findScreenAtDisplay().
+'height' and 'width' is the height and width of the entire screen. It is
+very tempting to use these a lot, but they are dangerous. The reason they
+are dangerous is that they span across all heads associated with that screen.
+Therefor, you want to familiarise yourself with the CompOutput structure.
+The CompScreen has an array of nOutputDev CompOutput structures, in other
+words, one per monitor. It also has a convenient currentOutputDev which core
+tries to set, but is not allways accurate.
+Luckily, the CompOutput struct is very simple. It has a width, height, region
+and workRegion variable that we care about. The region helps us established
+where a outputDev starts in the screen. region.x1 defines where the X-coordinate
+of that specific window starts, and region.x2 describes where it ends. The same
+with region.y1/y2 respectivly for the Y coordinate.
+For a single monitor with 1024x768, the outputdev will look like this:
+x1: 0
+x2: 1023
+y1: 0
+y2: 767
+Keep in mind that x + width puts you 1 pixel beyond the device. (0-1023 is 1024
+numbers. A classical programming error is to forget that 0 is a valid number).
+Currently, we don't really use the rects of the regions, so for nowe we can
+ignore those.
+workRegion is identical to region, but is supposed to take struts into
+consideration. This code has undergone some changes, and is likely to change
+in the future. The problem is that we never used the region-nature of the
+workRegion so it was still just a rect. That discussion is beyond the scope
+of this text, however. Just keep it in mind if you want a simple but imperfect
+way of avoiding panels.
+So when do you use s->width and when do you use
+s->outpudDev[s->currentOutputDev].region.x1/x2 ? There is no universal answer
+to this, but the simple answer is to use s->width when you are concerned with
+the entire screen, and the outputDev when you want to constrain yourself to the
+monitor. Examples are maximization which deals with outputDev, and edge-
+detection which wants to find the edge of the screen, not the monitor.
+More obvious variables are hsize and vsize, which defines the horisontal
+and vertical size. x/y which defines which of these you are currently on,
+screenNum which defines which screen you are on (usually 0), the WorkArea
+rectangle which defines the work area for the screen (avoid using this, as
+it will be quite strange on xinerama-hinted multihead.)
+Each CompScreen also has a list of windows (s->windows) and the reversed
+version. Windows are stored in a bottom-up fashion, so the first window in
+s->windows will be the bottom most window.
+The projectionStyle sets how the projection matrix should be set up. This
+is mostly just relevant for xinerama multihead at the moment. See the multihead
+documentation for details. In the future, this might be used to set orthographic
+projection instead of perspective.
+5. CompWindow
+Each window has a CompWindow structure. However, you should not store this link
+unless you also make sure you listen for events which would destroy it and
+update your version accordingly. If you want your plugin to remember a window,
+it is often wise to use the w->id instead, and locate the CompWindow when you
+need it, bu this depends on how you use the CompWindow. Storing the CompWindow
+pointer is faster, but slightly more complex.
+6. Regions
diff --git a/PaintLocking b/PaintLocking
new file mode 100644
index 0000000..0b18e1d
--- /dev/null
+++ b/PaintLocking
@@ -0,0 +1,102 @@
+Locking paint window paint attributes
+1. About this document
+2. Basic design
+3. Usage
+1. About this document
+This document is more a quick overview than an in-depth description.
+The functions are well documented in the code, please read them for more
+In this document, paint attributes are opacity, saturation and brightness.
+They also deal with CompWindow's not, for instance, cube transparancy.
+2. Basic design
+We assume there are three fundamentally diffrent ways to change paint
+attributes. These are:
+ - Human change or external program. These should get precedence.
+ - Plugin wanting a permanent change for their lifetime.
+ - Plugin wanting a temporary effect.
+To facilitate these three diffrent cases, we store paint-values two
+plces. They are stored in w->paint, which is the actual paint values
+used, and they are stored in w->opacity/saturation/brightness (I'll use
+w->opacity though all three apply from now on).
+Traditionally, w->opacity represented the atom, and did not change unless
+we changed an atom. At the same time, plugins hardly used w->paint.* at, but
+instead wrapped paintWindow() to change the opacity at each repaint of the
+The way we do things now, we use w->opacity as a default value, and
+w->paint.opacity as the real value. We try to avoid using paintWindow()
+to change the opacity.
+A plugin that wish to temporarily change the opacity, will do so by
+modifying w->paint.opacity, and when it is finished, it wil set
+w->paint.opacity to w->opacity. While it is set, it will lock w->paint.opacity.
+This lock is usually set to PL_TEMP_HELLO, which is a pseudo-lock. The
+reason we don't use PL_NO_LOCK, is to avoid overriding the temporary change
+when the default is changed.
+Now consider two plugins, trailfocus and opacify. Opacify is modifying opacity
+on 5 windows, and we change focus. This causes trailfocus to change w->opacity
+on these 5 windows, but the change isn't visible until opacify decides to reset
+the opacity.
+The assumption is that a user using trailfocus wants the opacity to be changed,
+but also wants to use opacify. The default change will live "forever" because
+trailfocus allways affects the opacity. As a fallback, when we unload
+trailfocus, core supplies a bailout function that sets w->opacity to the
+atom-defined value.
+The diffrent levels of locking allow us to override other plugins. This is
+used in state, and this is used when manually changing opacity. A user-initated
+opacity change will change w->opacity and at the same time lock it so other
+code, like trailfocus, is unable to change it. State has the ability to lock
+both the default and temporary/absoloute paint attributes. State simply
+sets default and temporary paint attributes with PL_PLUGIN_ONE. Users may
+want to use this for ensuring their mplayer-window is allways opaque for
+3. Usage
+Unless you intend the paint change to last until you unload, you want
+to use the
+setWindowOpacity(CompWindow * w, GLushort opacity, PaintLockLevels lock);
+resetWindowOpacity(CompWindow * w, PaintLockLevels lock);
+set of functions (and the respective functions for brightness/saturation).
+You should not have to worry about return-values, though setWindowOpacity()
+will return true if it successfully sets the value.
+Generally, you use PL_TEMP_HELLO as the lock, state uses PL_PLUGIN_ONE. We
+adjust lock levels on a case-by-case basis. There is really no more magic
+behind this.
+If you are writing something similar to state or trailfocus, or otherwise
+want to define the opacity the user sees on the window "all the time", you
+will have to use these:
+setDefaultWindowOpacity(CompWindow *w, GLushort opacity, PaintLockLevels lock);
+setWindowBailoutOpacity(CompWindow *w, PaintLockLevels lock);
+Here, you will use PL_NO_LOCK or PL_PLUGIN_x, (IE: Everything but PL_TEMP_HELLO
+and PL_SUPER).
+The bailout is intended for configuration changes (when a user suddenly no
+longer want state to handle a window for instance), and plugin unload. Do not
+use the Bailout* functions lightly.
+Examples of usage:
+Opacify (temp)
+Move (temp)
+Resize (temp)
+Trailfocus (default)
+State (default and temp)
+Core (mouse-wheel and atom-changes) (default)