~ubuntu-branches/ubuntu/edgy/hwinfo/edgy

« back to all changes in this revision

Viewing changes to src/hd/fb.c

  • Committer: Bazaar Package Importer
  • Author(s): James Vega
  • Date: 2006-09-28 20:56:06 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20060928205606-bgxl69hts04xbx51
Tags: 13.4-1
* New upstream version.
* Switch from dbs to quilt
  - Revamp debian/rules
  - Add quilt and remove dbs from Build-Depends in debian/control
* Remove reference to hwscan(8) from manpage. (closes: #388245)
* Re-wrote manpage from scratch.  Drop docbook-to-man from Build-Depends.
* Remove NEWS.Debian since it is no longer applicable.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <stdio.h>
 
2
#include <stdlib.h>
 
3
#include <string.h>
 
4
#include <unistd.h>
 
5
#include <fcntl.h>
 
6
#include <sys/types.h>
 
7
#include <sys/stat.h>
 
8
#include <sys/ioctl.h>
 
9
#include <linux/hdreg.h>
 
10
#include <linux/fb.h>
 
11
 
 
12
#include "hd.h"
 
13
#include "hd_int.h"
 
14
#include "fb.h"
 
15
 
 
16
/**
 
17
 * @defgroup Framebuffer Framebuffer devices
 
18
 * @ingroup  libhdDEVint
 
19
 * @brief Scan framebuffer devices
 
20
 *
 
21
 * @{
 
22
 */
 
23
 
 
24
typedef struct {
 
25
  unsigned width;
 
26
  unsigned height;
 
27
  double pix_clock;
 
28
  double h_freq;
 
29
  double v_freq;
 
30
} fb_info_t;
 
31
 
 
32
static fb_info_t *fb_get_info(hd_data_t *hd_data);
 
33
 
 
34
void hd_scan_fb(hd_data_t *hd_data)
 
35
{
 
36
  fb_info_t *fb;
 
37
  hd_t *hd;
 
38
  hd_res_t *res;
 
39
  unsigned imac_dev, imac_vend;
 
40
  unsigned imac = 0;
 
41
  monitor_info_t *mi = NULL;
 
42
 
 
43
  if(!hd_probe_feature(hd_data, pr_fb)) return;
 
44
 
 
45
  hd_data->module = mod_fb;
 
46
 
 
47
  /* some clean-up */
 
48
  remove_hd_entries(hd_data);
 
49
 
 
50
  PROGRESS(1, 0, "read info");
 
51
 
 
52
  fb = fb_get_info(hd_data);
 
53
 
 
54
  if(fb) {
 
55
    imac_dev = MAKE_ID(TAG_EISA, 0x9d03);
 
56
    imac_vend = name2eisa_id("APP");
 
57
 
 
58
    for(hd = hd_data->hd; hd; hd = hd->next) {
 
59
      if(hd->base_class.id == bc_monitor) break;
 
60
    }
 
61
 
 
62
    if(hd && hd->device.id == imac_dev && hd->vendor.id == imac_vend) {
 
63
      hd->tag.remove = 1;
 
64
      remove_tagged_hd_entries(hd_data);
 
65
      imac = 1;
 
66
      hd = NULL;
 
67
    }
 
68
 
 
69
    /* add monitor entry based on fb data if we have no other info */
 
70
    if(!hd) {
 
71
      hd = add_hd_entry(hd_data, __LINE__, 0);
 
72
      hd->base_class.id = bc_monitor;
 
73
      if(imac) {
 
74
        hd->vendor.id = imac_vend;
 
75
        hd->device.id = imac_dev;
 
76
      }
 
77
      else {
 
78
        hd->vendor.name = new_str("Generic");
 
79
        hd->device.name = new_str("Monitor");
 
80
      }
 
81
 
 
82
      res = add_res_entry(&hd->res, new_mem(sizeof *res));
 
83
      res->monitor.type = res_monitor;
 
84
      res->monitor.width = fb->width;
 
85
      res->monitor.height = fb->height;
 
86
      res->monitor.vfreq = fb->v_freq + 0.5;
 
87
 
 
88
      if(!hd->detail) {
 
89
        mi = new_mem(sizeof *mi);
 
90
        hd->detail = new_mem(sizeof *hd->detail);
 
91
        hd->detail->type = hd_detail_monitor;
 
92
        hd->detail->monitor.data = mi;
 
93
 
 
94
        mi->min_vsync = 50;
 
95
        mi->min_hsync = 31;
 
96
        mi->max_vsync = fb->v_freq * 1.11 + 0.9;
 
97
        mi->max_hsync = fb->h_freq / 1000.0 + 1.9;
 
98
        if(mi->max_vsync <= mi->min_vsync) mi->max_vsync = mi->min_vsync + 10;
 
99
        if(mi->max_hsync <= mi->min_hsync) mi->max_hsync = mi->min_hsync + 5;
 
100
        /* round up */
 
101
        mi->max_vsync = ((mi->max_vsync + 9) / 10) * 10;
 
102
      }
 
103
    }
 
104
  }
 
105
}
 
106
 
 
107
fb_info_t *fb_get_info(hd_data_t *hd_data)
 
108
{
 
109
  int fd;
 
110
  struct fb_var_screeninfo fbv_info;
 
111
  static fb_info_t fb_info;
 
112
  fb_info_t *fb = NULL;
 
113
  int h, v;
 
114
 
 
115
  fd = open(DEV_FB, O_RDONLY);
 
116
  if(fd < 0) fd = open(DEV_FB0, O_RDONLY);
 
117
  if(fd < 0) return fb;
 
118
 
 
119
  if(!ioctl(fd, FBIOGET_VSCREENINFO, &fbv_info)) {
 
120
    h = fbv_info.left_margin + fbv_info.xres + fbv_info.right_margin + fbv_info.hsync_len;
 
121
    v = fbv_info.upper_margin + fbv_info.yres + fbv_info.lower_margin + fbv_info.vsync_len;
 
122
    if(fbv_info.pixclock && h && v) {
 
123
      fb_info.width = fbv_info.xres;
 
124
      fb_info.height = fbv_info.yres;
 
125
      fb_info.pix_clock = 1e12 / fbv_info.pixclock;
 
126
      fb_info.h_freq = fb_info.pix_clock / h;
 
127
      fb_info.v_freq = fb_info.h_freq / v;
 
128
      fb = &fb_info;
 
129
      ADD2LOG("fb: size %d x %d\n", fb_info.width, fb_info.height);
 
130
      ADD2LOG("fb: timing %.2f MHz, %.2f kHz, %.2f Hz\n", fb_info.pix_clock * 1e-6, fb_info.h_freq * 1e-3, fb_info.v_freq);
 
131
    }
 
132
  }
 
133
 
 
134
  close(fd);
 
135
 
 
136
  return fb;
 
137
}
 
138
 
 
139
/** @} */
 
140