File slim-1.3.1-xinerama.patch of Package slim

--- INSTALL
+++ INSTALL
@@ -2,6 +2,7 @@
 
 0. Prerequisites:
  - X.org or XFree86
+ - libXinerama
  - libxmu
  - libpng
  - libjpeg
--- Makefile
+++ Makefile
@@ -18,7 +18,7 @@
 OPTFLAGS=
 CFLAGS=$(OPTFLAGS) -I. -I$(INCLUDEDIR) -I$(INCLUDEDIR)/freetype2 -I$(INCLUDEDIR)/freetype2/config -I$(INCLUDEDIR)/libpng12
 CXXFLAGS=$(CFLAGS)
-LDFLAGS=-L$(LIBDIR) -lXft -lX11 -lfreetype -lXrender -lfontconfig -lpng12 -lz -lm -lcrypt -lXmu -lpng -ljpeg
+LDFLAGS=-L$(LIBDIR) -lXft -lX11 -lXinerama -lfreetype -lXrender -lfontconfig -lpng12 -lz -lm -lcrypt -lXmu -lpng -ljpeg
 ifdef USE_PAM
 LDFLAGS+= -lpam
 CUSTOM+= -DUSE_PAM
--- README
+++ README
@@ -15,6 +15,7 @@
     - XFT / freetype support
     - Double or single (GDM-style) inputbox support
     - Automake-based build procedure
+    - Xinerama support
 
 INSTALLATION
     see the INSTALL file
@@ -40,8 +41,9 @@
     is to take a screenshot if the 'import' program is available.
     
 CONFIGURATION
-    /usr/etc/slim.conf is the main configuration file.
-    Options are explained in the file itself
+    /etc/slim.conf is the main configuration file, or use the -f
+    option.
+    Options are explained in the file itself.
     
 THEMES
     See THEMES
--- app.cpp
+++ app.cpp
@@ -315,8 +315,30 @@
         blankScreen();
     }
 
+    int screenCount;
+    XineramaScreenInfo *screens = XineramaQueryScreens(Dpy, &screenCount);
+    if (screens != NULL) {
+        bool ok;
+        int screen = Cfg::string2int(cfg->getOption("xinerama_screen").c_str(), &ok);
+        if (!ok || screen >= screenCount)
+            screen = 0;
+        screenInfo = (XineramaScreenInfo *)malloc(sizeof(XineramaScreenInfo));
+        if (screenInfo == NULL) {
+            fprintf(stderr, "Can't allocate memory for Xinerama screeninfo.\n");
+            exit(ERR_EXIT);
+        }
+        memcpy(screenInfo, &screens[screen], sizeof(XineramaScreenInfo));
+        XFree(screens);
+    }
+
     HideCursor();
 
+    if (!testing && XineramaIsActive(Dpy)) {
+      Root = XCreateSimpleWindow(Dpy, Root, ScreenLeft(), ScreenTop(), ScreenWidth(), ScreenHeight(), 0, 0, 0);
+      XMapWindow(Dpy, Root);
+      XFlush(Dpy);
+    }
+
     // Create panel
     LoginPanel = new Panel(Dpy, Scr, Root, cfg, themedir);
     bool firstloop = true; // 1st time panel is shown (for automatic username)
@@ -708,8 +730,8 @@
     int posy = 40;
     int fontx = 9;
     int fonty = 15;
-    int width = (XWidthOfScreen(ScreenOfDisplay(Dpy, Scr)) - (posx * 2)) / fontx;
-    int height = (XHeightOfScreen(ScreenOfDisplay(Dpy, Scr)) - (posy * 2)) / fonty;
+    int width = (ScreenWidth() - (posx * 2)) / fontx;
+    int height = (ScreenHeight() - (posy * 2)) / fonty;
 
     // Execute console
     const char* cmd = cfg->getOption("console_cmd").c_str();
@@ -742,6 +764,8 @@
         RemoveLock();
     }
     delete cfg;
+    if (screenInfo != NULL)
+        free(screenInfo);
     exit(OK_EXIT);
 }
 
@@ -1011,13 +1035,45 @@
     GC gc = XCreateGC(Dpy, Root, 0, 0);
     XSetForeground(Dpy, gc, BlackPixel(Dpy, Scr));
     XFillRectangle(Dpy, Root, gc, 0, 0,
-                   XWidthOfScreen(ScreenOfDisplay(Dpy, Scr)),
-                   XHeightOfScreen(ScreenOfDisplay(Dpy, Scr)));
+                   XWidthOfScreen(ScreenOfDisplay(Dpy, Scr)),   // intentional
+                   XHeightOfScreen(ScreenOfDisplay(Dpy, Scr))); // intentional
     XFlush(Dpy);
     XFreeGC(Dpy, gc);
 
 }
 
+int App::ScreenLeft()
+{
+    if (screenInfo == NULL)
+        return 0;
+    else
+        return screenInfo->x_org;
+}
+
+int App::ScreenTop()
+{
+    if (screenInfo == NULL)
+        return 0;
+    else
+        return screenInfo->y_org;
+}
+
+int App::ScreenWidth()
+{
+    if (screenInfo == NULL)
+        return XWidthOfScreen(ScreenOfDisplay(Dpy, Scr));
+    else
+        return screenInfo->width;
+}
+
+int App::ScreenHeight()
+{
+    if (screenInfo == NULL)
+        return XHeightOfScreen(ScreenOfDisplay(Dpy, Scr));
+    else
+        return screenInfo->height;
+}
+
 void App::setBackground(const string& themedir) {
     string filename;
     filename = themedir + "/background.png";
@@ -1031,18 +1087,18 @@
     if (loaded) {
         string bgstyle = cfg->getOption("background_style");
         if (bgstyle == "stretch") {
-            image->Resize(XWidthOfScreen(ScreenOfDisplay(Dpy, Scr)), XHeightOfScreen(ScreenOfDisplay(Dpy, Scr)));
+            image->Resize(ScreenWidth(), ScreenHeight());
         } else if (bgstyle == "tile") {
-            image->Tile(XWidthOfScreen(ScreenOfDisplay(Dpy, Scr)), XHeightOfScreen(ScreenOfDisplay(Dpy, Scr)));
+            image->Tile(ScreenWidth(), ScreenHeight());
         } else if (bgstyle == "center") {
             string hexvalue = cfg->getOption("background_color");
             hexvalue = hexvalue.substr(1,6);
-            image->Center(XWidthOfScreen(ScreenOfDisplay(Dpy, Scr)), XHeightOfScreen(ScreenOfDisplay(Dpy, Scr)),
+            image->Center(ScreenWidth(), ScreenHeight(),
                         hexvalue.c_str());
         } else { // plain color or error
             string hexvalue = cfg->getOption("background_color");
             hexvalue = hexvalue.substr(1,6);
-            image->Center(XWidthOfScreen(ScreenOfDisplay(Dpy, Scr)), XHeightOfScreen(ScreenOfDisplay(Dpy, Scr)),
+            image->Center(ScreenWidth(), ScreenHeight(),
                         hexvalue.c_str());
         }
         Pixmap p = image->createPixmap(Dpy, Scr, Root);
--- app.h
+++ app.h
@@ -13,6 +13,7 @@
 #define _APP_H_
 
 #include <X11/Xlib.h>
+#include <X11/extensions/Xinerama.h>
 #include <signal.h>
 #include <unistd.h>
 #include <sys/wait.h>
@@ -40,6 +41,8 @@
     void GetLock();
     void RemoveLock();
 
+    friend class Panel;
+
 private:
     void Login();
     void Reboot();
@@ -69,10 +72,16 @@
     int ServerTimeout(int timeout, char *string);
     int WaitForServer();
 
+    int ScreenLeft();
+    int ScreenTop();
+    int ScreenWidth();
+    int ScreenHeight();
+
     // Private data
     Window Root;
     Display* Dpy;
     int Scr;
+    XineramaScreenInfo* screenInfo;
     Panel* LoginPanel;
     int ServerPID;
     const char* DisplayName;
--- cfg.cpp
+++ cfg.cpp
@@ -56,6 +56,7 @@
     options.insert(option("sessions","wmaker,blackbox,icewm"));
     options.insert(option("sessiondir",""));
     options.insert(option("hidecursor","false"));
+    options.insert(option("xinerama_screen", "0"));
 
     // Theme stuff
     options.insert(option("input_panel_x","50%"));
--- panel.cpp
+++ panel.cpp
@@ -11,9 +11,12 @@
 
 #include <sstream>
 #include "panel.h"
+#include "app.h"
 
 using namespace std;
 
+extern App* LoginApp;
+
 Panel::Panel(Display* dpy, int scr, Window root, Cfg* config,
              const string& themedir) {
     // Set display
@@ -105,28 +108,27 @@
             }
         }
     }
+
     if (bgstyle == "stretch") {
-        bg->Resize(XWidthOfScreen(ScreenOfDisplay(Dpy, Scr)), XHeightOfScreen(ScreenOfDisplay(Dpy, Scr)));
+        bg->Resize(LoginApp->ScreenWidth(), LoginApp->ScreenHeight());
     } else if (bgstyle == "tile") {
-        bg->Tile(XWidthOfScreen(ScreenOfDisplay(Dpy, Scr)), XHeightOfScreen(ScreenOfDisplay(Dpy, Scr)));
+        bg->Tile(LoginApp->ScreenWidth(), LoginApp->ScreenHeight());
     } else if (bgstyle == "center") {
         string hexvalue = cfg->getOption("background_color");
         hexvalue = hexvalue.substr(1,6);
-        bg->Center(XWidthOfScreen(ScreenOfDisplay(Dpy, Scr)),
-                   XHeightOfScreen(ScreenOfDisplay(Dpy, Scr)),
+        bg->Center(LoginApp->ScreenWidth(), LoginApp->ScreenHeight(),
                    hexvalue.c_str());
     } else { // plain color or error
         string hexvalue = cfg->getOption("background_color");
         hexvalue = hexvalue.substr(1,6);
-        bg->Center(XWidthOfScreen(ScreenOfDisplay(Dpy, Scr)),
-                   XHeightOfScreen(ScreenOfDisplay(Dpy, Scr)),
+        bg->Center(LoginApp->ScreenWidth(), LoginApp->ScreenHeight(),
                    hexvalue.c_str());
     }
 
     string cfgX = cfg->getOption("input_panel_x");
     string cfgY = cfg->getOption("input_panel_y");
-    X = Cfg::absolutepos(cfgX, XWidthOfScreen(ScreenOfDisplay(Dpy, Scr)), image->Width());
-    Y = Cfg::absolutepos(cfgY, XHeightOfScreen(ScreenOfDisplay(Dpy, Scr)), image->Height());
+    X = Cfg::absolutepos(cfgX, LoginApp->ScreenWidth(), image->Width());
+    Y = Cfg::absolutepos(cfgY, LoginApp->ScreenHeight(), image->Height());
 
     // Merge image into background
     image->Merge(bg, X, Y);
@@ -210,8 +212,8 @@
     int shadowYOffset =
         Cfg::string2int(cfg->getOption("msg_shadow_yoffset").c_str());
 
-    int msg_x = Cfg::absolutepos(cfgX, XWidthOfScreen(ScreenOfDisplay(Dpy, Scr)), extents.width);
-    int msg_y = Cfg::absolutepos(cfgY, XHeightOfScreen(ScreenOfDisplay(Dpy, Scr)), extents.height);
+    int msg_x = Cfg::absolutepos(cfgX, LoginApp->ScreenWidth(), extents.width);
+    int msg_y = Cfg::absolutepos(cfgY, LoginApp->ScreenHeight(), extents.height);
 
     SlimDrawString8 (draw, &msgcolor, msgfont, msg_x, msg_y,
                      text,
@@ -585,8 +587,8 @@
                     currsession.length(), &extents);
     msg_x = cfg->getOption("session_x");
     msg_y = cfg->getOption("session_y");
-    int x = Cfg::absolutepos(msg_x, XWidthOfScreen(ScreenOfDisplay(Dpy, Scr)), extents.width);
-    int y = Cfg::absolutepos(msg_y, XHeightOfScreen(ScreenOfDisplay(Dpy, Scr)), extents.height);
+    int x = Cfg::absolutepos(msg_x, LoginApp->ScreenWidth(), extents.width);
+    int y = Cfg::absolutepos(msg_y, LoginApp->ScreenHeight(), extents.height);
     int shadowXOffset =
         Cfg::string2int(cfg->getOption("session_shadow_xoffset").c_str());
     int shadowYOffset =
--- slim.conf
+++ slim.conf
@@ -16,6 +16,8 @@
 # Xauth file for server
 authfile           /var/run/slim.auth
 
+# Xinerama screen to show login panel on (zero-based)
+# xinerama_screen    0
 
 # Activate numlock when slim starts. Valid values: on|off
 # numlock             on
openSUSE Build Service is sponsored by