~ubuntu-branches/ubuntu/raring/gnustep-back/raring

« back to all changes in this revision

Viewing changes to Source/x11/XGServerWindow.m

  • Committer: Package Import Robot
  • Author(s): Benjamin Drung
  • Date: 2012-11-21 22:57:37 UTC
  • mfrom: (1.2.9) (15.1.1 raring-proposed)
  • Revision ID: package-import@ubuntu.com-20121121225737-rme3qx928vtesqo7
Tags: 0.22.0-1ubuntu1
* Merge from Debian experimental. Remaining change:
  - debian/rules (build-arch) Depend on debian/build-indep-stamp to build
    the docs files included in every package.

Show diffs side-by-side

added added

removed removed

Lines of Context:
57
57
// For X_HAVE_UTF8_STRING
58
58
#include <X11/Xlib.h>
59
59
#include <X11/cursorfont.h>
60
 
 
 
60
#if HAVE_XCURSOR
 
61
#include <X11/Xcursor/Xcursor.h>
 
62
#endif
 
63
#ifdef HAVE_XSHAPE
61
64
#include <X11/extensions/shape.h>
 
65
#endif
62
66
 
63
67
#include "x11/XGDragView.h"
64
68
#include "x11/XGInputServer.h"
759
763
  root = [self _rootWindowForScreen: defScreen];
760
764
  context = [self xrContextForScreen: defScreen];
761
765
 
762
 
  window = malloc(sizeof(gswindow_device_t));
 
766
  window = NSAllocateCollectable(sizeof(gswindow_device_t), NSScannedOption);
763
767
  memset(window, '\0', sizeof(gswindow_device_t));
764
768
  window->display = dpy;
765
769
  window->screen = defScreen;
1274
1278
          
1275
1279
          // Window state
1276
1280
          generic.netstates.net_wm_state_atom = 
1277
 
              XInternAtom(dpy, "_NET_WM_STATE", False);
 
1281
            XInternAtom(dpy, "_NET_WM_STATE", False);
 
1282
          generic.netstates.new_wm_state_modal_atom = 
 
1283
            XInternAtom(dpy, "_NET_WM_STATE_MODAL", False);
 
1284
          generic.netstates.net_wm_state_sticky_atom = 
 
1285
            XInternAtom(dpy, "_NET_WM_STATE_STICKY", False);
 
1286
          generic.netstates.net_wm_state_maximized_vert_atom = 
 
1287
            XInternAtom(dpy, "_NET_WM_STATE_MAXIMIZED_VERT", False);     
 
1288
          generic.netstates.net_wm_state_maximized_horz_atom = 
 
1289
            XInternAtom(dpy, "_NET_WM_STATE_MAXIMIZED_HORZ", False);
 
1290
          generic.netstates.net_wm_state_shaded_atom = 
 
1291
            XInternAtom(dpy, "_NET_WM_STATE_SHADED", False);
1278
1292
          generic.netstates.net_wm_state_skip_taskbar_atom = 
1279
 
              XInternAtom(dpy, "_NET_WM_STATE_SKIP_TASKBAR", False);
 
1293
            XInternAtom(dpy, "_NET_WM_STATE_SKIP_TASKBAR", False);
1280
1294
          generic.netstates.net_wm_state_skip_pager_atom = 
1281
 
              XInternAtom(dpy, "_NET_WM_STATE_SKIP_PAGER", False);
1282
 
          generic.netstates.net_wm_state_sticky_atom = 
1283
 
              XInternAtom(dpy, "_NET_WM_STATE_STICKY", False);
 
1295
            XInternAtom(dpy, "_NET_WM_STATE_SKIP_PAGER", False);
1284
1296
          generic.netstates.net_wm_state_hidden_atom = 
1285
 
              XInternAtom(dpy, "_NET_WM_STATE_HIDDEN", False);
 
1297
            XInternAtom(dpy, "_NET_WM_STATE_HIDDEN", False);
 
1298
          generic.netstates.net_wm_state_fullscreen_atom = 
 
1299
            XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False);
 
1300
          generic.netstates.net_wm_state_above_atom = 
 
1301
            XInternAtom(dpy, "_NET_WM_STATE_ABOVE", False);
 
1302
          generic.netstates.net_wm_state_below_atom = 
 
1303
            XInternAtom(dpy, "_NET_WM_STATE_BELOW", False);
 
1304
          generic.netstates.net_wm_state_demands_attention_atom = 
 
1305
            XInternAtom(dpy, "_NET_WM_STATE_DEMANDS_ATTENTION", False);
1286
1306
        }
1287
1307
      if (win1)
1288
1308
        {
1312
1332
  if (window)
1313
1333
    return window;
1314
1334
 
1315
 
  window = malloc(sizeof(gswindow_device_t));
 
1335
  window = NSAllocateCollectable(sizeof(gswindow_device_t), NSScannedOption);
1316
1336
  memset(window, '\0', sizeof(gswindow_device_t));
1317
1337
 
1318
1338
  window->display = dpy;
1447
1467
  if ((generic.wm & XGWM_EWMH) != 0)
1448
1468
    {
1449
1469
      window->protocols[window->numProtocols++] = generic.net_wm_ping_atom;
 
1470
#ifdef HAVE_LIBXEXT
 
1471
      window->protocols[window->numProtocols++] = generic.net_wm_sync_request_atom;
 
1472
#endif
1450
1473
    }
1451
1474
  if ((generic.wm & XGWM_WINDOWMAKER) != 0
1452
1475
      && (window->win_attrs.window_style & NSMiniaturizableWindowMask) != 0)
1453
1476
    {
1454
1477
      window->protocols[window->numProtocols++] = generic.miniaturize_atom;
1455
1478
    }
 
1479
  NSAssert1(window->numProtocols <= GSMaxWMProtocols,
 
1480
            @"Too many protocols (%d > GSMaxWMProtocols)",
 
1481
            window->numProtocols);
1456
1482
  XSetWMProtocols(dpy, window->ident, window->protocols, window->numProtocols);
1457
1483
}
1458
1484
 
1484
1510
  generic.delete_win_atom = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
1485
1511
  generic.wm_state_atom = XInternAtom(dpy, "WM_STATE", False);
1486
1512
  generic.net_wm_ping_atom = XInternAtom(dpy, "_NET_WM_PING", False);
 
1513
  generic.net_wm_sync_request_atom = XInternAtom(dpy, "_NET_WM_SYNC_REQUEST", False);
 
1514
  generic.net_wm_sync_request_counter_atom = XInternAtom(dpy, "_NET_WM_SYNC_REQUEST_COUNTER", False);
1487
1515
  generic.miniaturize_atom
1488
1516
    = XInternAtom(dpy, "_GNUSTEP_WM_MINIATURIZE_WINDOW", False);
1489
1517
  generic.win_decor_atom = XInternAtom(dpy,"_GNUSTEP_WM_ATTR", False);
1938
1966
 
1939
1967
  /* Create the window structure and set the style early so we can use it to
1940
1968
  convert frames. */
1941
 
  window = malloc(sizeof(gswindow_device_t));
 
1969
  window = NSAllocateCollectable(sizeof(gswindow_device_t), NSScannedOption);
1942
1970
  memset(window, '\0', sizeof(gswindow_device_t));
1943
1971
  window->display = dpy;
1944
1972
  window->screen = screen;
2074
2102
  // All the windows of a GNUstep application belong to one group.
2075
2103
  window->gen_hints.flags |= WindowGroupHint;
2076
2104
  window->gen_hints.window_group = ROOT;
 
2105
  
 
2106
#ifdef HAVE_LIBXEXT
 
2107
  /**
 
2108
   * Setup net_wm_sync_request_counter
 
2109
   */
 
2110
  {
 
2111
    XSyncValue value;
 
2112
    XSyncIntToValue(&value, 0);
 
2113
    window->net_wm_sync_request_counter = XSyncCreateCounter(dpy, value);
 
2114
    XChangeProperty(dpy,
 
2115
                    window->ident,
 
2116
                    generic.net_wm_sync_request_counter_atom,
 
2117
                    XA_CARDINAL,
 
2118
                    32,
 
2119
                    PropModeReplace,
 
2120
                    (unsigned char *) &(window->net_wm_sync_request_counter),
 
2121
                    1);
 
2122
    window->net_wm_sync_request_counter_value_low = 0;
 
2123
    window->net_wm_sync_request_counter_value_high = 0;
 
2124
  }
 
2125
#endif
2077
2126
 
2078
2127
  /*
2079
2128
   * Prepare the protocols supported by the window.
2136
2185
 
2137
2186
  /* Create the window structure and set the style early so we can use it to
2138
2187
  convert frames. */
2139
 
  window = malloc(sizeof(gswindow_device_t));
 
2188
  window = NSAllocateCollectable(sizeof(gswindow_device_t), NSScannedOption);
2140
2189
  memset(window, '\0', sizeof(gswindow_device_t));
2141
2190
  window->display = dpy;
2142
2191
  window->screen = *screen;
2266
2315
    XDestroyRegion (window->region);
2267
2316
  RELEASE(window->exposedRects);
2268
2317
  NSMapRemove(windowtags, (void*)(uintptr_t)win);
2269
 
  free(window);
 
2318
  NSZoneFree(0, window);
2270
2319
}
2271
2320
 
2272
2321
/*
2985
3034
            (NSIconWindowMask|NSMiniWindowMask)) != 0))
2986
3035
        {
2987
3036
          /*
2988
 
           * Make any window which assumes the desktop level act as the background.
 
3037
           * Make any window which assumes the desktop level act as the
 
3038
           * background.
2989
3039
           */ 
2990
 
          if(window->win_attrs.window_level == NSDesktopWindowLevel) 
 
3040
          if (window->win_attrs.window_level == NSDesktopWindowLevel) 
2991
3041
            {
2992
3042
              [self _sendRoot: window->root 
2993
3043
                    type: generic.netstates.net_wm_state_atom
2999
3049
            }
3000
3050
          else
3001
3051
            {
 
3052
              BOOL sticky = NO;
 
3053
              NSUserDefaults *defs = [NSUserDefaults standardUserDefaults];
 
3054
 
3002
3055
              [self _sendRoot: window->root 
3003
3056
                    type: generic.netstates.net_wm_state_atom
3004
3057
                    window: window->ident
3005
3058
                    data0: _NET_WM_STATE_ADD
3006
3059
                    data1: generic.netstates.net_wm_state_skip_taskbar_atom
3007
3060
                    data2: generic.netstates.net_wm_state_skip_pager_atom
3008
 
                data3: 1];
 
3061
                    data3: 1];
 
3062
 
 
3063
              if ((window->win_attrs.window_style & NSIconWindowMask) != 0)
 
3064
                {
 
3065
                  sticky = [defs boolForKey: @"GSStickyAppIcons"];
 
3066
                }
 
3067
              else if ((window->win_attrs.window_style & NSMiniWindowMask) != 0)
 
3068
                {
 
3069
                  sticky = [defs boolForKey: @"GSStickyMiniWindows"];
 
3070
                }
 
3071
              if (sticky == YES)
 
3072
                {
 
3073
                  [self _sendRoot: window->root 
 
3074
                             type: generic.netstates.net_wm_state_atom
 
3075
                           window: window->ident
 
3076
                            data0: _NET_WM_STATE_ADD
 
3077
                            data1: generic.netstates.net_wm_state_sticky_atom
 
3078
                            data2: 0
 
3079
                            data3: 1];
 
3080
                }
3009
3081
            }
3010
3082
        }
3011
3083
    }
3029
3101
      return;
3030
3102
    }
3031
3103
 
 
3104
#ifdef HAVE_XSHAPE
3032
3105
  if ([[image backgroundColor] alphaComponent] * 256 <= ALPHA_THRESHOLD)
3033
3106
    {
3034
3107
      // The mask computed here is only correct for unscaled images.
3053
3126
    {
3054
3127
      XFreePixmap(dpy, pixmap);
3055
3128
    }
 
3129
#endif
3056
3130
}
3057
3131
 
3058
3132
/* This method is a fast implementation of move that only works 
3620
3694
        }
3621
3695
    }
3622
3696
 
 
3697
#ifdef HAVE_LIBXEXT
 
3698
  if (window->net_wm_sync_request_counter_value_low != 0 
 
3699
      || window->net_wm_sync_request_counter_value_high != 0) 
 
3700
    {
 
3701
      XSyncValue value;
 
3702
      XSyncIntsToValue(&value,
 
3703
                       window->net_wm_sync_request_counter_value_low,
 
3704
                       window->net_wm_sync_request_counter_value_high);
 
3705
      XSyncSetCounter(dpy, window->net_wm_sync_request_counter, value);
 
3706
      window->net_wm_sync_request_counter_value_low = 0;
 
3707
      window->net_wm_sync_request_counter_value_high = 0;
 
3708
    }
 
3709
#endif
 
3710
 
3623
3711
  XFlush(dpy);
3624
3712
}
3625
3713
 
4198
4286
- (void) imagecursor: (NSPoint)hotp : (NSImage *)image : (void **)cid
4199
4287
{
4200
4288
  Cursor cursor;
4201
 
  Pixmap source, mask;
4202
 
  unsigned int maxw, maxh;
4203
 
  XColor fg, bg;
4204
4289
  NSBitmapImageRep *rep;
4205
4290
  int w, h;
4206
4291
  int colors;
4232
4317
      return;
4233
4318
    }
4234
4319
 
4235
 
  /* FIXME: Handle this better or return an error? */
4236
 
  XQueryBestCursor(dpy, ROOT, w, h, &maxw, &maxh);
4237
 
  if ((unsigned int)w > maxw)
4238
 
    w = maxw;
4239
 
  if ((unsigned int)h > maxh)
4240
 
    h = maxh;
4241
 
 
4242
 
  source = xgps_cursor_image(dpy, ROOT, data, w, h, colors, &fg, &bg);
4243
 
  mask = xgps_cursor_mask(dpy, ROOT, data, w, h, colors);
4244
 
  bg = [self xColorFromColor: bg forScreen: defScreen];
4245
 
  fg = [self xColorFromColor: fg forScreen: defScreen];
4246
 
 
4247
 
  cursor = XCreatePixmapCursor(dpy, source, mask, &fg, &bg, 
4248
 
                               (int)hotp.x, (int)hotp.y);
4249
 
  XFreePixmap(dpy, source);
4250
 
  XFreePixmap(dpy, mask);
 
4320
#if HAVE_XCURSOR
 
4321
  // FIXME: Standardize getStandardBitmap() so it always returns
 
4322
  // alpha, and document the format.
 
4323
  if (colors != 4)
 
4324
    {
 
4325
      *cid = NULL;
 
4326
      return;
 
4327
    }
 
4328
 
 
4329
  {
 
4330
    XcursorImage *xcursorImage;
 
4331
    xcursorImage = XcursorImageCreate(w, h);
 
4332
    xcursorImage->xhot = hotp.x;
 
4333
    xcursorImage->yhot = hotp.y;
 
4334
 
 
4335
    // Copy the data from the image rep to the Xcursor structure
 
4336
    {
 
4337
      int bytesPerRow;
 
4338
      size_t row;
 
4339
 
 
4340
      bytesPerRow = [rep bytesPerRow];
 
4341
 
 
4342
      for (row = 0; row < h; row++)
 
4343
        {
 
4344
          memcpy((char*)xcursorImage->pixels + (row * (w * 4)),
 
4345
                 data + (row * bytesPerRow),
 
4346
                 bytesPerRow);
 
4347
        }
 
4348
    }
 
4349
 
 
4350
    // FIXME: Factor this out
 
4351
    // Convert RGBA unpacked to BGRA packed
 
4352
    {
 
4353
      NSInteger stride;
 
4354
      NSInteger x, y;
 
4355
      unsigned char *cdata;
 
4356
      
 
4357
      stride = 4 * w;
 
4358
      cdata = (unsigned char *)xcursorImage->pixels;
 
4359
      
 
4360
      for (y = 0; y < h; y++)
 
4361
        {
 
4362
          for (x = 0; x < w; x++)
 
4363
            {
 
4364
              NSInteger i = (y * stride) + (x * 4);
 
4365
              unsigned char d = cdata[i];
 
4366
              
 
4367
#if GS_WORDS_BIGENDIAN
 
4368
              cdata[i] = cdata[i + 1];
 
4369
              cdata[i + 1] = cdata[i + 2];
 
4370
              cdata[i + 2] = cdata[i + 3];
 
4371
              cdata[i + 3] = d;
 
4372
#else
 
4373
              cdata[i] = cdata[i + 2];
 
4374
              //cdata[i + 1] = cdata[i + 1];
 
4375
              cdata[i + 2] = d;
 
4376
              //cdata[i + 3] = cdata[i + 3];
 
4377
#endif 
 
4378
            }
 
4379
        }
 
4380
    }
 
4381
    
 
4382
    cursor = XcursorImageLoadCursor(dpy, xcursorImage);
 
4383
    XcursorImageDestroy(xcursorImage);
 
4384
  }
 
4385
#else // !HAVE_XCURSOR
 
4386
  {
 
4387
    Pixmap source, mask;
 
4388
    unsigned int maxw, maxh;
 
4389
    XColor fg, bg;
 
4390
 
 
4391
    /* FIXME: Handle this better or return an error? */
 
4392
    XQueryBestCursor(dpy, ROOT, w, h, &maxw, &maxh);
 
4393
    if ((unsigned int)w > maxw)
 
4394
      w = maxw;
 
4395
    if ((unsigned int)h > maxh)
 
4396
      h = maxh;
 
4397
    
 
4398
    source = xgps_cursor_image(dpy, ROOT, data, w, h, colors, &fg, &bg);
 
4399
    mask = xgps_cursor_mask(dpy, ROOT, data, w, h, colors);
 
4400
    bg = [self xColorFromColor: bg forScreen: defScreen];
 
4401
    fg = [self xColorFromColor: fg forScreen: defScreen];
 
4402
    
 
4403
    cursor = XCreatePixmapCursor(dpy, source, mask, &fg, &bg, 
 
4404
                                 (int)hotp.x, (int)hotp.y);
 
4405
    XFreePixmap(dpy, source);
 
4406
    XFreePixmap(dpy, mask);
 
4407
  }
 
4408
#endif
 
4409
 
4251
4410
  if (cid)
4252
4411
    *cid = (void *)cursor;
4253
4412
}
4418
4577
 
4419
4578
- (NSSize) resolutionForScreen: (int)screen_num
4420
4579
 
4580
  // NOTE:
 
4581
  // -gui now trusts the return value of resolutionForScreen:,
 
4582
  // so if it is not {72, 72} then the entire UI will be scaled.
 
4583
  //
 
4584
  // I commented out the implementation below because it may not
 
4585
  // be safe to use the DPI value we get from the X server.
 
4586
  // (i.e. I don't know if it will be a "fake" DPI like 72 or 96,
 
4587
  //  or a real measurement reported from the monitor's firmware
 
4588
  //  (possibly incorrect?))
 
4589
  // More research needs to be done.
 
4590
 
 
4591
  return NSMakeSize(72, 72);
 
4592
 
 
4593
  /*
4421
4594
  int res_x, res_y;
4422
4595
 
4423
4596
  if (screen_num < 0 || screen_num >= ScreenCount(dpy))
4432
4605
      (DisplayHeightMM(dpy, screen_num) / 25.4);
4433
4606
        
4434
4607
  return NSMakeSize(res_x, res_y);
 
4608
  */
4435
4609
}
4436
4610
 
4437
4611
- (NSRect) boundsForScreen: (int)screen